All Files (73.05% covered at 53.45 hits/line)
315 files in total.
13019 relevant lines.
9511 lines covered and
3508 lines missed
-
1
class AnalyticsController < ApplicationController
-
1
def index
-
@analytics = User.order("confirmation_sent_at DESC").page(params[:page]).per_page(15)
-
respond_to do |format|
-
format.html
-
end
-
end
-
end
-
1
class AndroidController < ApplicationController
-
1
protect_from_forgery :except => :submission
-
1
before_filter :authenticate_user!
-
1
helper_method :render_xform, :get_hash_from_xml, :prepare_site
-
-
3
expose(:collections) { Collection.accessible_by(current_ability) }
-
-
-
1
ODKFORM_TEMPLATE = "public/odk_form_template.xml"
-
-
1
def collections_json
-
2
collection_array=[]
-
2
collections.each do |collection|
-
2
collection_hash = collection.attributes
-
2
collection_hash["form"] = render_xform(collection)
-
2
collection_array.push collection_hash
-
end
-
2
render :json => collection_array
-
end
-
-
1
def render_xform(collection)
-
7
if File.exist? ODKFORM_TEMPLATE
-
7
File.open ODKFORM_TEMPLATE, "r" do |file|
-
7
xform = Xform.new(file.read)
-
7
xform.render_form(collection)
-
end
-
else
-
""
-
end
-
end
-
-
1
def submission
-
2
xml_hash = HashParser.from_xml_file(params["xml_submission_file"]).values.first.merge("current_user" => current_user)
-
2
if current_user.admins?(Collection.find(xml_hash["collection_id"]))
-
1
render json: Site.create_or_update_from_hash!(xml_hash)
-
else
-
1
render text: "User is unauthorized", status: 401
-
end
-
end
-
-
end
-
1
class Api::CollectionsController < ApplicationController
-
1
include Api::JsonHelper
-
1
include Api::GeoJsonHelper
-
1
include Concerns::CheckApiDocs
-
-
1
before_filter :authenticate_api_user!
-
1
skip_before_filter :verify_authenticity_token
-
1
before_filter :check_user_member_admin!, :only => [:update_sites]
-
1
before_filter :check_user_member!, :only => [:show, :geo_json, :get_sites_conflict, :get_some_sites]
-
-
1
def index
-
render json: current_user.collections, :root => false
-
end
-
-
1
def show
-
23
options = [:sort]
-
-
23
if params[:format] == 'csv' || params[:page] == 'all'
-
15
options << :all
-
15
params.delete(:page)
-
elsif params[:format] == 'kml' || params[:format] == 'shp'
-
2
options << :require_location
-
2
options << :page
-
else
-
6
options << :page
-
end
-
23
@results = perform_search *options
-
-
16
collection.time_zone = current_user.time_zone
-
16
respond_to do |format|
-
18
format.rss { render :show, layout: false }
-
24
format.csv { collection_csv(collection, @results) }
-
20
format.json { render json: collection_json(collection, @results) }
-
16
format.kml { collection_kml(collection, @results) }
-
18
format.shp { collection_shp(collection, @results) }
-
end
-
end
-
-
1
def export_layers
-
respond_to do |format|
-
format.json {send_data layers.to_json(include: :fields.as_json(:except => [:id]), :except => [:id, :ord, :collection_id]), filename: "#{collection.name}_layers.json"}
-
end
-
end
-
-
1
def download_location_csv
-
field = fields.find(params[:field])
-
location_csv = collection.location_csv(field.config["locations"]) if field.config["locations"]
-
send_data location_csv, type: 'text/csv', filename: "#{field.name}_locations.csv"
-
end
-
-
1
def sample_csv
-
respond_to do |format|
-
format.csv { collection_sample_csv(collection) }
-
end
-
end
-
-
1
def collection_sample_csv(collection)
-
sample_csv = collection.sample_csv current_user
-
send_data sample_csv, type: 'text/csv', filename: "#{collection.name}_sites.csv"
-
end
-
-
1
def count
-
render json: perform_search(:count).total
-
end
-
-
1
def geo_json
-
@results = perform_search :page, :sort, :require_location
-
render json: collection_geo_json(collection, @results)
-
end
-
-
1
def update_sites
-
index = 0
-
array_site_ids = params[:site_id].split(",")
-
array_user_email = params[:user_email].split(",")
-
array_site_ids.each do |el|
-
site = Site.find_by_id(el)
-
site.user = User.find_by_email(array_user_email[index])
-
site.user = User.first
-
site.lat = params[:lat]
-
site.lng = params[:lng]
-
if site.valid?
-
site.save!
-
else
-
render json: site.errors.messages, status: :unprocessable_entity, :layout => false
-
end
-
index = index + 1
-
end
-
render json: {status: 201}
-
end
-
-
1
def get_fields
-
fields = Collection.find(params[:id]).fields
-
list = []
-
fields.each do |f|
-
obj = {}
-
obj["code"] = f.code
-
obj["id"] = f.id
-
obj["name"] = f.name
-
obj["kind"] = f.kind
-
obj["options"] = f.config["options"] if f.config["options"]
-
list.push obj
-
end
-
render :json => list.to_json
-
end
-
-
1
def get_sites_conflict
-
if params[:con_type]
-
sites = []
-
con_type = params[:con_type].split(",")
-
collection = Collection.find_by_id(params[:id])
-
properties = collection.fields.find_by_code(params[:field_code]).id
-
if (params[:from].blank? && params[:to].blank?)
-
from = parse_date_format("#{Time.now.mon}/01/#{Time.now.year}") - 1
-
to = parse_date_format("#{Time.now.mon}/30/#{Time.now.year}").end_of_month + 1
-
tmp_sites = Collection.find(params[:id]).sites.where(:created_at => from..to).each do |x|
-
con_type.each do |el|
-
if x.properties["#{properties}"] == el.to_i
-
sites << x
-
end
-
end
-
end
-
else
-
from = parse_date_format(params[:from]) - 1
-
to = parse_date_format(params[:to]) + 1
-
tmp_sites = Collection.find(params[:id]).sites.where(:created_at => from..to).each do |x|
-
con_type.each do |el|
-
if x.properties["#{properties}"] == el.to_i
-
sites << x
-
end
-
end
-
end
-
end
-
else
-
sites = Collection.find(params[:id]).sites
-
end
-
render :json => sites
-
end
-
-
1
def get_some_sites
-
1
site_ids = params[:sites]
-
1
sites = Site.where("id in (" + site_ids + ")")
-
1
render :json => sites, :root => false
-
end
-
-
1
def parse_date_format date
-
array_date = date.split("-")
-
return Date.new(array_date[2].to_i, array_date[0].to_i, array_date[1].to_i)
-
end
-
-
1
def sites_by_term
-
search = new_search
-
-
search.full_text_search params[:term] if params[:term]
-
search.alerted_search params[:_alert] if params[:_alert]
-
search.select_fields(['id', 'name', 'properties'])
-
# search.apply_queries
-
-
results = search.results.map{ |item| item["fields"]}
-
-
results.each do |item|
-
item[:value] = item["name"]
-
end
-
-
render json: results
-
end
-
-
1
private
-
-
1
def perform_search(*options)
-
23
except_params = [:action, :controller, :format, :id, :updated_since, :search, :box, :lat, :lng, :radius]
-
-
23
search = new_search
-
-
23
search.use_codes_instead_of_es_codes
-
-
23
if options.include? :page
-
8
search.page params[:page].to_i if params[:page]
-
8
except_params << :page
-
elsif options.include? :count
-
search.offset 0
-
search.limit 0
-
elsif options.include? :all
-
15
search.unlimited
-
end
-
-
23
search.after params[:updated_since] if params[:updated_since]
-
23
search.full_text_search params[:search] if params[:search]
-
23
search.box *valid_box_coordinates if params[:box]
-
-
23
if params[:lat] || params[:lng] || params[:radius]
-
[:lat, :lng, :radius].each do |key|
-
raise "Missing '#{key}' parameter" unless params[key]
-
raise "Missing '#{key}' value" unless !params[key].blank?
-
-
end
-
search.radius params[:lat], params[:lng], params[:radius]
-
end
-
-
23
if options.include? :require_location
-
2
search.require_location
-
end
-
-
23
if options.include? :sort
-
23
search.sort params[:sort], params[:sort_direction] != 'desc' if params[:sort]
-
23
except_params << :sort
-
23
except_params << :sort_direction
-
end
-
23
search.where params.except(*except_params)
-
16
search.api_results
-
end
-
-
1
def valid_box_coordinates
-
coords = params[:box].split ','
-
raise "Expected the 'box' parameter to be four comma-separated numbers" if coords.length != 4
-
-
coords.each_with_index do |coord, i|
-
Float(coord) rescue raise "Expected #{(i + 1).ordinalize} value of 'box' parameter to be a number, not '#{coord}'"
-
end
-
-
coords
-
end
-
-
1
def collection_csv(collection, results)
-
8
sites_csv = collection.to_csv results, current_user
-
8
send_data sites_csv, type: 'text/csv', filename: "#{collection.name}_sites.csv"
-
end
-
-
1
def collection_shp(collection, results)
-
2
send_data collection.to_shp(results), type: 'application/zip', filename: "#{collection.id}.zip"
-
end
-
-
1
def collection_kml(collection, results)
-
sites_kml = collection.to_kml results
-
send_data sites_kml, type: 'application/vnd.google-earth.kml+xml', filename: "#{collection.name}_sites.kml"
-
end
-
-
1
def visible_layer_for_site
-
-
end
-
-
1
def check_user_member_admin!
-
collection = Collection.find_by_id(params[:collection_id])
-
if (current_user.collections.map(&:id).include?(params["id"].to_i)and current_user.admins?(collection))
-
return true
-
else
-
return head 403
-
end
-
end
-
-
1
def check_user_member!
-
24
collection = Collection.find_by_id(params[:collection_id])
-
24
if (current_user.collections.map(&:id).include?(params["id"].to_i))
-
24
return true
-
else
-
return head 403
-
end
-
end
-
-
end
-
1
class Api::SitesController < ApplicationController
-
1
include Api::JsonHelper
-
-
# before_filter :authenticate_user!
-
# before_filter :authenticate_site_user!
-
-
1
before_filter :authenticate_api_user!
-
1
before_filter :check_user_member!
-
-
1
expose(:site)
-
3
expose(:collection) { site.collection }
-
-
1
def show
-
2
search = new_search
-
-
2
search.id(site.id)
-
2
@result = search.api_results[0]
-
-
2
respond_to do |format|
-
4
format.rss { render :show, layout: false }
-
2
format.json { render json: site_item_json(@result) }
-
end
-
end
-
-
1
def update
-
1
site = Site.find_by_id(params[:id])
-
1
site.lat = params[:lat]
-
1
site.lng = params[:lng]
-
1
site.name = params[:name]
-
# properties = prepare_site_property params
-
1
if params[:properties]
-
1
properties = params[:properties]
-
1
site.properties = properties
-
end
-
1
unless current_user
-
site.user = User.find_by_phone_number(params[:phone_number])
-
else
-
1
site.user = current_user
-
end
-
1
if site.valid?
-
1
site.save!
-
1
render json: {site: site, status: 201}
-
end
-
end
-
-
1
def destroy
-
1
site = Site.find_by_id(params[:id])
-
1
site.destroy
-
1
render json: {site: site}
-
end
-
-
1
def create
-
1
site_params = {}
-
# properties = prepare_site_property params
-
1
site_params.merge!("name" => params[:name])
-
1
site_params.merge!("lat" => params[:lat])
-
1
site_params.merge!("lng" => params[:lng])
-
1
site_params.merge!("properties" => params[:properties])
-
1
current_user = User.find_by_phone_number(params[:phone_number])
-
1
collection = Collection.find_by_id(params[:collection_id])
-
1
site = collection.sites.new(site_params.merge!(user: current_user))
-
1
if site.valid?
-
1
site.save!
-
1
current_user.site_count += 1
-
1
current_user.update_successful_outcome_status
-
1
current_user.save!(:validate => false)
-
1
render json: {site: site, status: 200}
-
else
-
render :text => "Error",:status => 500
-
end
-
-
end
-
-
1
def prepare_site_property params
-
properties = {}
-
conflict_state_id = Field.find_by_code("con_state").id.to_s
-
conflict_type_id = Field.find_by_code("con_type").id.to_s
-
conflict_intensity_id = Field.find_by_code("con_intensity").id.to_s
-
properties.merge!(conflict_state_id => params[:conflict_state])
-
properties.merge!(conflict_type_id => params[:conflict_type])
-
properties.merge!(conflict_intensity_id => params[:conflict_intensity])
-
-
return properties
-
end
-
-
1
def index
-
2
builder = Collection.filter_sites(params)
-
2
sites_size = builder.size
-
2
sites_by_page = Collection.filter_page(params[:limit], params[:offset], builder)
-
2
render :json => {:sites => sites_by_page, :total => sites_size}
-
end
-
-
1
def get_reporter_site
-
builder = Collection.filter_sites(params)
-
sites_size = builder.size
-
sites_by_page = Collection.filter_page(params[:limit], params[:offset], builder)
-
render :json => {:sites => sites_by_page, :total => sites_size}
-
end
-
-
1
private
-
-
1
def check_user_member!
-
7
collection = Collection.find_by_id(params[:collection_id])
-
7
if (current_user.collections.map(&:id).include?(params["collection_id"].to_i))
-
7
return true
-
else
-
return head 403
-
end
-
end
-
-
end
-
1
module Api::V1
-
1
class SitesController < ApplicationController
-
1
include Concerns::CheckApiDocs
-
1
include Api::JsonHelper
-
-
1
before_filter :authenticate_api_user!
-
1
before_filter :check_user_member!
-
1
skip_before_filter :verify_authenticity_token
-
3
expose(:site) { Site.find(params[:site_id] || params[:id]) }
-
-
1
def index
-
2
builder = Collection.filter_sites(params)
-
-
2
sites_size = builder.size
-
2
sites_by_page = Collection.filter_page_order_by_name(params[:limit], params[:offset], builder)
-
2
render :json => {:sites => sites_by_page, :total => sites_size}
-
end
-
-
1
def show
-
search = new_search
-
-
search.id params[:id]
-
result = search.ui_results.first['_source'] rescue {}
-
render json: result
-
end
-
-
1
def update
-
1
site.attributes = sanitized_site_params(false).merge(user: current_user)
-
1
if site.valid?
-
1
site.save!
-
1
if params[:photosToRemove]
-
Site::UploadUtils.purgePhotos(params[:photosToRemove])
-
end
-
1
render json: site, :layout => false
-
else
-
render json: site.errors.messages, status: :unprocessable_entity, :layout => false
-
end
-
end
-
-
1
def create
-
6
site = build_site
-
6
create_state = site.id ? false : true #to create or update
-
6
if site.save
-
6
if create_state
-
5
current_user.site_count += 1
-
5
current_user.update_successful_outcome_status
-
5
current_user.save!(:validate => false)
-
end
-
6
render json: site, status: :created
-
else
-
render json: site.errors.messages, status: :unprocessable_entity
-
end
-
end
-
-
1
def visible_layers_for
-
layers = []
-
if site.collection.site_ids_permission(current_user).include? site.id
-
target_fields = fields.includes(:layer).all
-
layers = target_fields.map(&:layer).uniq.map do |layer|
-
{
-
id: layer.id,
-
name: layer.name,
-
ord: layer.ord,
-
}
-
end
-
if site.collection.site_ids_write_permission(current_user).include? site.id
-
layers.each do |layer|
-
layer[:fields] = target_fields.select { |field| field.layer_id == layer[:id] }
-
layer[:fields].map! do |field|
-
{
-
id: field.es_code,
-
name: field.name,
-
code: field.code,
-
kind: field.kind,
-
config: field.config,
-
ord: field.ord,
-
is_mandatory: field.is_mandatory,
-
is_enable_field_logic: field.is_enable_field_logic,
-
writeable: true
-
}
-
end
-
end
-
elsif site.collection.site_ids_read_permission(current_user).include? site.id
-
layers.each do |layer|
-
layer[:fields] = target_fields.select { |field| field.layer_id == layer[:id] }
-
layer[:fields].map! do |field|
-
{
-
id: field.es_code,
-
name: field.name,
-
code: field.code,
-
kind: field.kind,
-
config: field.config,
-
ord: field.ord,
-
is_mandatory: field.is_mandatory,
-
is_enable_field_logic: field.is_enable_field_logic,
-
writeable: false
-
}
-
end
-
end
-
end
-
layers.sort! { |x, y| x[:ord] <=> y[:ord] }
-
else
-
layers = site.collection.visible_layers_for(current_user)
-
end
-
render json: layers
-
end
-
-
1
def prepare_site_property params
-
properties = {}
-
conflict_state_id = Field.find_by_code("con_state").id.to_s
-
conflict_type_id = Field.find_by_code("con_type").id.to_s
-
conflict_intensity_id = Field.find_by_code("con_intensity").id.to_s
-
properties.merge!(conflict_state_id => params[:conflict_state])
-
properties.merge!(conflict_type_id => params[:conflict_type])
-
properties.merge!(conflict_intensity_id => params[:conflict_intensity])
-
-
return properties
-
end
-
-
1
private
-
1
def sanitized_site_params new_record
-
7
parameters = params[:site]
-
-
7
result = new_record ? {} : site.filter_site_by_id(params[:id])
-
-
7
fields = collection.fields.index_by &:es_code
-
7
site_properties = parameters.delete("properties") || {}
-
-
7
files = parameters.delete("files") || {}
-
-
7
decoded_properties = new_record ? {} : result.properties
-
7
site_properties.each_pair do |es_code, value|
-
12
value = [ value, files[value] ] if fields[es_code].kind_of? Field::PhotoField
-
12
decoded_properties[es_code] = fields[es_code].decode_from_ui(value) if fields[es_code]
-
end
-
-
7
parameters["properties"] = decoded_properties
-
7
parameters
-
end
-
-
1
def build_site
-
6
site = collection.is_site_exist? params[:site][:device_id], params[:site][:external_id] if params[:site][:device_id]
-
6
if site
-
1
params[:id] = site.id
-
1
site.attributes = sanitized_site_params(false).merge(user: current_user)
-
else
-
5
site = collection.sites.build sanitized_site_params(true).merge(user: current_user)
-
end
-
6
return site
-
end
-
-
1
def check_user_member!
-
9
collection = Collection.find_by_id(params[:collection_id])
-
9
if (current_user.collections.map(&:id).include?(params["collection_id"].to_i))
-
9
return true
-
else
-
return head 403
-
end
-
end
-
-
end
-
end
-
1
class ApplicationController < ActionController::Base
-
1
helper :all
-
1
protect_from_forgery
-
-
1
include Concerns::MobileDeviceDetection
-
-
-
1
expose(:collection)
-
27
expose(:current_user_snapshot) { UserSnapshot.for current_user, collection }
-
1
expose(:collection_memberships){ collection.memberships.includes(:user) }
-
3
expose(:layers) {if !current_user_snapshot.at_present? && collection then collection.layer_histories.at_date(current_user_snapshot.snapshot.date) else collection.layers end}
-
1
expose(:layer)
-
1
expose(:fields) {if !current_user_snapshot.at_present? && collection then collection.field_histories.at_date(current_user_snapshot.snapshot.date) else collection.fields end}
-
1
expose(:activities) { current_user.activities }
-
1
expose(:thresholds) { collection.thresholds.order :ord }
-
1
expose(:threshold)
-
1
expose(:reminders) { collection.reminders }
-
1
expose(:reminder)
-
1
expose(:language) { Language.find_by_code I18n.locale.to_s }
-
-
1
expose(:new_search_options) do
-
23
if current_user_snapshot.at_present?
-
23
{current_user: current_user}
-
else
-
{snapshot_id: current_user_snapshot.snapshot.id, current_user_id: current_user.id}
-
end
-
end
-
22
expose(:new_search) { collection.new_search new_search_options }
-
-
1
rescue_from ActiveRecord::RecordNotFound do |x|
-
2
render :file => '/error/doesnt_exist_or_unauthorized', :status => 404, :layout => true
-
end
-
-
1
rescue_from CanCan::AccessDenied do |exception|
-
4
render :file => '/error/doesnt_exist_or_unauthorized', :alert => exception.message, :status => :forbidden
-
end
-
-
1
before_filter :set_timezone
-
1
before_filter :set_locale
-
1
before_filter :store_location
-
1
before_filter :set_request_header
-
-
-
1
def store_location
-
108
return unless request.get?
-
if (request.path != "/users/sign_in" &&
-
46
request.path != "/users/sign_up" &&
-
request.path != "/users/password/new" &&
-
request.path != "/users/password/edit" &&
-
request.path != "/users/confirmation" &&
-
request.path != "/users/sign_out" &&
-
!request.xhr?)
-
46
session[:previous_url] = request.fullpath
-
end
-
end
-
-
1
def set_locale
-
108
cookies.signed[:locale] = params[:locale] || cookies.signed[:locale] || I18n.default_locale
-
108
I18n.locale = cookies.signed[:locale]
-
end
-
-
1
def set_timezone
-
# current_user.time_zone #=> 'London'
-
99
Time.zone = current_user.time_zone if current_user
-
end
-
-
1
def setup_guest_user
-
12
u = User.new
-
12
u.is_guest = true
-
# Empty membership for the current collection
-
# This is used in SitesPermissionController.index
-
# TODO: Manage permissions passing current_ability to client
-
12
membership = Membership.new
-
12
membership.collection_id = collection.id
-
12
u.memberships = [membership]
-
12
@guest_user = u
-
end
-
-
1
def current_user
-
631
super || @guest_user
-
end
-
-
1
def current_user_or_guest
-
if user_signed_in?
-
return if !current_user.try(:is_guest)
-
end
-
-
if params.has_key? "collection"
-
return if !Collection.find(params["collection"]).public
-
u = User.find_by_is_guest true
-
sign_in :user, u
-
current_user.is_login = true
-
current_user.save!(:validate => false)
-
else
-
if current_user.try(:is_login)
-
current_user.is_login = false
-
current_user.save!(:validate => false)
-
else
-
sign_out :user
-
end
-
end
-
end
-
-
1
def after_sign_in_path_for(resource)
-
if mobile_device?
-
stored_location_for(resource) || mobile_collections_path
-
else
-
stored_location_for(resource) || collections_path
-
end
-
end
-
-
1
def authenticate_api_admin_user!
-
params.delete :auth_token if current_user
-
unless current_user
-
basic_authentication_admin_check
-
end
-
end
-
-
1
def basic_authentication_admin_check
-
user = User.find_by_authentication_token(params.delete :auth_token) and sign_in user and user.is_super_user
-
end
-
-
1
def authenticate_collection_user!
-
head :forbidden unless current_user.belongs_to?(collection)
-
end
-
-
1
def authenticate_collection_admin!
-
4
head :forbidden unless current_user.admins?(collection)
-
end
-
-
1
def authenticate_site_user!
-
head :forbidden unless current_user.belongs_to?(site.collection)
-
end
-
-
1
def show_collections_breadcrumb
-
9
@show_breadcrumb = true
-
end
-
-
1
def show_collection_breadcrumb
-
7
show_collections_breadcrumb
-
7
add_breadcrumb I18n.t('views.collections.index.collections'), collections_path
-
7
add_breadcrumb collection.name, collections_path + "?collection_id=#{collection.id}"
-
end
-
-
1
def show_properties_breadcrumb
-
2
add_breadcrumb I18n.t('views.collections.index.properties'), collection_path(collection)
-
end
-
-
1
def get_user_auth_token
-
if current_user
-
render :text => current_user.authentication_token, :layout => false
-
else
-
render :text => nil
-
end
-
end
-
-
1
def basic_authentication_check
-
user = User.find_by_authentication_token(params.delete :auth_token) and sign_in user
-
http_basic_authentication unless user
-
end
-
-
1
def http_basic_authentication
-
authenticate_or_request_with_http_basic do |user, password|
-
resource = User.find_by_email(user)
-
if resource && resource.valid_password?(password)
-
sign_in resource
-
true
-
else
-
head :forbidden
-
end
-
end
-
end
-
-
1
def set_request_header
-
108
headers['Access-Control-Allow-Origin'] = '*'
-
end
-
-
# Faster way to render json, using the Oj library.
-
# There is a way to let render :json use Oj by default,
-
# but in my tests it turned out to be slower... - Ary
-
1
def render_json(object, options = {})
-
2
options = options.merge(text: object.to_json_oj, content_type: 'application/json')
-
2
render options
-
end
-
-
1
def authenticate_api_user!
-
40
params.delete :auth_token if current_user
-
40
unless current_user
-
basic_authentication_check
-
end
-
end
-
-
1
def ignore_public_attribute
-
params[:layer].delete(:public) if params[:layer] && params[:layer][:public]
-
end
-
-
end
-
1
class ChannelsAccessesController < ApplicationController
-
1
before_filter :authenticate_user!
-
-
1
def index
-
@collections = Collection.joins(:users)
-
@channels = Channel.where(:national_setup=>true) if current_user.is_super_user
-
@channels.each do |c|
-
p c.name
-
end
-
@collections.each do |c|
-
p c.name
-
p c.users
-
end
-
# users = User.all()
-
# @collections = []
-
# users.each do |u|
-
# collectionsUser = Collection.joins(:memberships).where("memberships.user_id = :user_id", :user_id => u.id)
-
# collectionsUser.each do |c|
-
# @collections.push({
-
# user_id: u.id,
-
# user_email: u.email,
-
# collection_id: c.id,
-
# collection_name: c.name,
-
# is_enabled_national_gateway: c.is_enabled_national_gateway})
-
# end
-
# end
-
# p @nationalGateways
-
end
-
-
1
def new
-
@shareNationalChannel = ShareNationalChannel.new
-
end
-
-
1
def create
-
@shareChannel = Collection.find(filter_params[:collection_id])
-
p @shareChannel
-
if @shareChannel.update_attributes(channel_ids: filter_params[:channel_id])
-
redirect_to channels_accesses_path, notice: 'Collection updated'
-
else
-
flash.now[:alert] = "Failed to update collection"
-
render :new
-
end
-
end
-
-
1
def create
-
p current_user
-
@collection = current_user.collections(params[:collection][:id])
-
if @collection.update_attributes(filter_params)
-
redirect_to national_gateways_path, notice: 'Project is granted access to the national gateway'
-
else
-
redirect_to national_gateways_path, alert: 'Fialed to grant access to national gateway'
-
end
-
end
-
-
1
def search_user
-
users = User.
-
where('email LIKE ?', "#{params[:term]}%").
-
order('email')
-
-
render json: users.pluck(:email)
-
end
-
-
1
def search_collection
-
collections = Collection.includes(:users).where('memberships.owner = ? ',1)
-
.where('name LIKE ?', "#{params[:term]}%").
-
order('name')
-
-
render json: collections.as_json(include: :users)
-
end
-
-
1
private
-
1
def filter_params
-
params.require(:collection).permit(:is_enabled_national_gateway)
-
end
-
end
-
1
class CollectionsController < ApplicationController
-
15
before_filter :setup_guest_user, :if => Proc.new { collection }
-
11
before_filter :authenticate_user!, :except => [:render_breadcrumbs, :index, :alerted_collections], :unless => Proc.new { collection }
-
-
1
authorize_resource :except => [:render_breadcrumbs], :decent_exposure => true, :id_param => :collection_id
-
-
1
expose(:collections){
-
11
if current_user && !current_user.is_guest
-
# public collections are accesible by all users
-
# here we only need the ones in which current_user is a member
-
9
current_user.collections
-
else
-
2
Collection.all
-
end
-
}
-
-
1
expose(:collections_with_snapshot) { select_each_snapshot(collections) }
-
-
1
before_filter :show_collections_breadcrumb, :only => [:index, :new]
-
1
before_filter :show_collection_breadcrumb, :except => [:index, :new, :create, :render_breadcrumbs]
-
1
before_filter :show_properties_breadcrumb, :only => [:members, :settings, :reminders, :quotas]
-
-
1
def index
-
2
if params[:name].present?
-
render json: Collection.where("name like ?", "%#{params[:name]}%") if params[:name].present?
-
else
-
2
add_breadcrumb I18n.t('views.collections.index.collections'), 'javascript:window.model.goToRoot()'
-
-
2
if current_user.is_guest
-
2
if params[:collection_id] && !collection.public?
-
flash[:error] = "You need to sign in order to view this collection"
-
redirect_to new_user_session_url
-
return
-
end
-
2
collections = Collection.public_collections
-
else
-
collections = current_user.collections.reject{|c| c.id.nil?}
-
end
-
-
2
respond_to do |format|
-
2
format.html
-
2
format.json { render json: collections, :root => false}
-
end
-
end
-
end
-
-
1
def render_breadcrumbs
-
add_breadcrumb I18n.t('views.collections.index.collections'), 'javascript:window.model.goToRoot()' if current_user && !current_user.is_guest
-
if params.has_key? :collection_id
-
add_breadcrumb collection.name, 'javascript:window.model.exitSite()'
-
if params.has_key? :site_id
-
add_breadcrumb params[:site_name], '#'
-
end
-
end
-
render :layout => false
-
end
-
-
1
def new
-
add_breadcrumb I18n.t('views.collections.index.collections'), collections_path
-
add_breadcrumb I18n.t('views.collections.form.create_new_collection'), nil
-
end
-
-
1
def create
-
1
if current_user.create_collection collection
-
1
current_user.collection_count += 1
-
1
current_user.update_successful_outcome_status
-
1
current_user.save!(:validate => false)
-
1
redirect_to collection_path(collection), notice: I18n.t('views.collections.form.collection_created', name: collection.name)
-
else
-
render :new
-
end
-
end
-
-
1
def update
-
if params[:collection][:hierarchy_mode] == "0"
-
params[:collection][:field_identify] = ""
-
params[:collection][:field_parent] = ""
-
end
-
if collection.update_attributes params[:collection]
-
collection.recreate_index
-
redirect_to collection_settings_path(collection), notice: I18n.t('views.collections.form.collection_updated', name: collection.name)
-
else
-
render :settings
-
end
-
end
-
-
1
def show
-
@snapshot = Snapshot.new
-
add_breadcrumb I18n.t('views.collections.index.properties'), '#'
-
respond_to do |format|
-
format.html
-
format.json { render json: collection }
-
end
-
end
-
-
1
def members
-
add_breadcrumb I18n.t('views.collections.tab.members'), collection_members_path(collection)
-
end
-
-
1
def reminders
-
add_breadcrumb I18n.t('views.collections.tab.reminders'), collection_reminders_path(collection)
-
end
-
-
1
def settings
-
@options_for_select = [["(no value)", ""]]
-
collection.fields.each do |field|
-
@options_for_select.push([field.name, field.id])
-
end
-
add_breadcrumb I18n.t('views.collections.tab.settings'), collection_settings_path(collection)
-
end
-
-
1
def quotas
-
add_breadcrumb I18n.t('views.collections.tab.quotas'), collection_settings_path(collection)
-
end
-
-
1
def destroy
-
if params[:only_sites]
-
collection.delete_sites_and_activities
-
redirect_to collection_path(collection), notice: I18n.t('views.collections.form.sites_deleted', name: collection.name)
-
else
-
collection.update_activities
-
collection.destroy
-
collection.create_deleted_activity(current_user)
-
redirect_to collections_path, notice: I18n.t('views.collections.form.collection_deleted', name: collection.name)
-
end
-
end
-
-
1
def csv_template
-
send_data collection.csv_template, type: 'text/csv', filename: "collection_sites_template.csv"
-
end
-
-
1
def upload_csv
-
collection.import_csv current_user, params[:file].read
-
redirect_to collections_path
-
end
-
-
1
def create_snapshot
-
@snapshot = Snapshot.create(date: Time.now, name: params[:snapshot][:name], collection: collection)
-
if @snapshot.valid?
-
redirect_to collection_path(collection), notice: I18n.t('views.collections.form.snapshot_created', name: params[:name])
-
else
-
flash[:error] = I18n.t('views.collections.form.snapshot_could_not_be_created', errors: @snapshot.errors.to_a.join(", "))
-
redirect_to collection_path(collection)
-
end
-
end
-
-
1
def unload_current_snapshot
-
1
loaded_snapshot = current_user_snapshot.snapshot
-
1
current_user_snapshot.go_back_to_present!
-
-
1
respond_to do |format|
-
1
format.html {
-
1
flash[:notice] = I18n.t('views.collections.form.snapshot_unloaded', name: loaded_snapshot.name) if loaded_snapshot if loaded_snapshot
-
1
redirect_to collection_path(collection) }
-
1
format.json { render json: :ok }
-
end
-
end
-
-
1
def load_snapshot
-
if current_user_snapshot.go_to!(params[:name])
-
redirect_to collection_path(collection), notice: I18n.t('views.collections.form.snapshot_loaded', name: params[:name])
-
end
-
end
-
-
1
def max_value_of_property
-
render json: collection.max_value_of_property(params[:property])
-
end
-
-
1
def select_each_snapshot(collections)
-
collections_with_snapshot = []
-
collections.each do |collection|
-
attrs = collection.attributes
-
# If user is guest (=> current_user will be nil) she will not be able to load a snapshot. At least for the moment
-
attrs["snapshot_name"] = collection.snapshot_for(current_user).try(:name) rescue nil
-
collections_with_snapshot = collections_with_snapshot + [attrs]
-
end
-
collections_with_snapshot
-
end
-
-
1
def sites_by_term
-
2
search = new_search
-
-
2
search.full_text_search params[:term] if params[:term]
-
2
search.alerted_search params[:_alert] if params[:_alert]
-
2
search.select_fields(['id', 'name'])
-
5
results = search.results.map { |item| item["fields"] }
-
2
results.each do |item|
-
3
item[:value] = item["name"]
-
end
-
-
2
render_json results
-
end
-
-
1
def search
-
search = new_search
-
-
search.after params[:updated_since] if params[:updated_since]
-
search.full_text_search params[:search]
-
search.offset params[:offset]
-
search.limit params[:limit]
-
search.alerted_search params[:_alert] if params[:_alert]
-
search.sort params[:sort], params[:sort_direction] != 'desc' if params[:sort]
-
search.hierarchy params[:hierarchy_code], params[:hierarchy_value] if params[:hierarchy_code]
-
search.location_missing if params[:location_missing].present?
-
search.where params.except(
-
:selected_site_children, :selected_site_parent,
-
:action, :controller, :format, :id, :collection_id,
-
:updated_since, :search, :limit, :offset, :sort, :sort_direction,
-
:hierarchy_code, :hierarchy_value, :location_missing, :_alert
-
)
-
-
-
# search.apply_queries
-
-
results = search.results.map do |result|
-
source = result['_source']
-
-
obj = {}
-
obj[:id] = source['id']
-
obj[:name] = source['name']
-
obj[:created_at] = Site.parse_time(source['created_at'])
-
obj[:updated_at] = Site.parse_time(source['updated_at'])
-
-
if source['location']
-
obj[:lat] = source['location']['lat']
-
obj[:lng] = source['location']['lon']
-
end
-
-
if source['properties']
-
obj[:properties] = source['properties']
-
end
-
-
obj
-
end
-
render json: results, :root => false
-
end
-
-
1
def decode_hierarchy_csv
-
csv_string = File.read(params[:file].path, :encoding => 'utf-8')
-
@hierarchy = collection.decode_hierarchy_csv(csv_string)
-
@hierarchy_errors = CollectionsController.generate_error_description_list(@hierarchy)
-
render layout: false
-
end
-
-
1
def decode_location_csv
-
csv_string = File.read(params[:file].path, :encoding => 'utf-8')
-
@locations = collection.decode_location_csv(csv_string)
-
@locations_errors = CollectionsController.generate_error_description_location(@locations)
-
render layout: false
-
end
-
-
1
def self.generate_error_description_location(locations_csv)
-
locations_errors = []
-
locations_csv.each do |item|
-
message = ""
-
-
if item[:error]
-
message << "Error: #{item[:error]}"
-
message << " " + item[:error_description] if item[:error_description]
-
message << " in line #{item[:order]}." if item[:order]
-
end
-
-
locations_errors << message if !message.blank?
-
end
-
locations_errors.join("<br/>").to_s
-
end
-
-
1
def self.generate_error_description_list(hierarchy_csv)
-
3
hierarchy_errors = []
-
3
hierarchy_csv.each do |item|
-
5
message = ""
-
5
if item[:error]
-
4
message << "Error: #{item[:error]}"
-
4
message << " " + item[:error_description] if item[:error_description]
-
4
message << " in line #{item[:order]}." if item[:order]
-
end
-
-
5
hierarchy_errors << message if !message.blank?
-
end
-
3
hierarchy_errors.join("<br/>").to_s
-
end
-
-
1
def recreate_index
-
render json: collection.recreate_index
-
end
-
-
1
def register_gateways
-
channels = []
-
channels = Channel.find params[:gateways] if params[:gateways].present?
-
collection.channels = channels
-
render json: collection.as_json
-
end
-
-
1
def message_quota
-
date = Date.today
-
case params[:filter_type]
-
when "week"
-
start_date = date - 7
-
when "month"
-
start_date = date.prev_month
-
else
-
start_date = date.prev_year
-
end
-
ms = collection.messages.where("is_send = true and created_at between ? and ?", start_date, Time.now)
-
render json: {status: 200, remain_quota: collection.quota, sended_message: ms.length }
-
end
-
-
1
def alerted_collections
-
collections = Collection.find_all_by_id params[:ids]
-
ids = collections.map do |c|
-
s = c.new_search
-
s.alerted_search true
-
# s.apply_queries
-
c.id if s.results.length > 0
-
end
-
render json: ids.compact, :root => false
-
end
-
-
1
def send_new_member_sms
-
random_code = (0..3).map{(rand(9))}.join
-
method = Channel.nuntium_info_methods
-
collection = Collection.find_by_id(params[:collection_id])
-
if channel = collection.channels.first
-
channel_detail = channel.as_json(methods: method)
-
if channel_detail[:client_connected]
-
SmsNuntium.notify_sms [params[:phone_number]], "Your single-use Resource Map pin code is #{random_code}", channel.nuntium_channel_name, nil
-
render json: {status: 200, secret_code: random_code}
-
else
-
render json: {status: 'channel_disconnected', notice: 'The channel is disconnected.'}
-
end
-
else
-
render json: {status: 'no_channel', notice: 'There is no channel on the collection.'}
-
end
-
end
-
-
1
def sites_info
-
2
options = new_search_options
-
-
2
total = collection.elasticsearch_count
-
2
no_location = collection.elasticsearch_count do
-
{
-
query: {
-
filtered: {
-
filter: {
-
not: {
-
filter: {
-
exists: {field: :location}
-
}
-
}
-
}
-
}
-
}
-
2
}
-
end
-
-
2
info = {}
-
2
info[:total] = total
-
2
info[:no_location] = no_location > 0
-
2
info[:new_site_properties] = collection.new_site_properties
-
-
2
render json: info
-
end
-
end
-
1
module Concerns::CheckApiDocs
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
2
around_filter :rescue_with_check_api_docs
-
end
-
-
1
def rescue_with_check_api_docs
-
33
yield
-
rescue => ex
-
-
9
Rails.logger.info ex.message
-
9
Rails.logger.info ex.backtrace
-
-
9
render text: "#{ex.message} - Check the API documentation: https://bitbucket.org/ilab/resource_map_sea/wiki/API", status: 400
-
end
-
end
-
1
module Concerns::MobileDeviceDetection
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
helper_method :mobile_device?
-
end
-
-
1
def mobile_device?
-
if params[:_desktop] == "1" || params[:_desktop] == "true"
-
return false
-
else
-
session[:desktop_param] = false
-
from_mobile_browser? || session[:mobile_param] == "1"
-
end
-
end
-
-
1
def from_mobile_browser?
-
!!(request.user_agent =~ /Mobile|webOS/)
-
end
-
-
1
def prepare_for_mobile
-
session[:mobile_param] = params[:mobile] if params[:mobile]
-
request.format = :mobile if mobile_device?
-
end
-
end
-
1
class GatewaysController < ApplicationController
-
1
before_filter :setup_guest_user, :only => :index
-
1
before_filter :authenticate_user!, :except => :index
-
-
1
def index
-
method = Channel.nuntium_info_methods
-
respond_to do |format|
-
format.html
-
format.json { render json: (params[:without_nuntium] ? current_user.channels.where("channels.is_enable=?", true).all.as_json : current_user.channels.select('channels.id,channels.name,channels.password,channels.is_enable,channels.basic_setup, channels.advanced_setup, channels.national_setup').all.as_json(methods: method)), :root => false}
-
end
-
end
-
-
1
def create
-
1
channel = current_user.channels.new params[:gateway]
-
1
if channel.valid?
-
1
channel.save!
-
1
current_user.gateway_count += 1
-
1
current_user.update_successful_outcome_status
-
1
current_user.save!(:validate => false)
-
1
render json: channel.as_json
-
else
-
render json: {status: 200, errors: channel.errors.full_messages}
-
end
-
end
-
-
1
def update
-
channel = Channel.find params[:id]
-
channel.update_attributes params[:gateway]
-
render json: channel
-
end
-
-
1
def destroy
-
channel = Channel.find params[:id]
-
channel.destroy
-
render json: channel
-
end
-
-
1
def try
-
channel = Channel.find params[:gateway_id]
-
SmsNuntium.notify_sms [params[:phone_number]], 'Welcome to resource map!', channel.nuntium_channel_name, nil
-
render json: channel.as_json
-
end
-
-
1
def status
-
1
channel = Channel.find params[:id]
-
1
channel.is_enable = params[:status]
-
1
channel.save!
-
1
render json: channel
-
end
-
end
-
1
class ImportWizardsController < ApplicationController
-
1
before_filter :authenticate_user!
-
1
before_filter :show_collection_breadcrumb
-
1
before_filter :show_properties_breadcrumb
-
1
before_filter :authenticate_collection_admin!, only: :logs
-
-
1
expose(:import_job) { ImportJob.last_for current_user, collection }
-
1
expose(:failed_import_jobs) { ImportJob.where(collection_id: collection.id).where(status: 'failed').order('id desc').page(params[:page]).per_page(10) }
-
-
1
def index
-
return redirect_to import_in_progress_collection_import_wizard_path(collection) if (import_job && (import_job.status_pending? || import_job.status_in_progress?))
-
-
add_breadcrumb I18n.t('views.collections.tab.import_wizard'), collection_import_wizard_path(collection)
-
end
-
-
1
def upload_csv
-
1
begin
-
1
ImportWizard.import current_user, collection, params[:file].original_filename, params[:file].read
-
1
redirect_to adjustments_collection_import_wizard_path(collection)
-
rescue => ex
-
redirect_to collection_import_wizard_path(collection), :alert => ex.message
-
end
-
end
-
-
1
def guess_columns_spec
-
render json: ImportWizard.guess_columns_spec(current_user, collection), :root =>false
-
end
-
-
1
def adjustments
-
add_breadcrumb I18n.t('views.collections.tab.import_wizard'), collection_import_wizard_path(collection)
-
end
-
-
1
def validate_sites_with_columns
-
render json: ImportWizard.validate_sites_with_columns(current_user, collection, JSON.parse(params[:columns]))
-
end
-
-
1
def execute
-
1
columns = params[:columns].values
-
5
if columns.find { |x| x[:usage] == 'new_field' } and not current_user.admins? collection
-
1
render text: I18n.t('views.import_wizards.cant_create_new_fields'), status: :unauthorized
-
else
-
ImportWizard.enqueue_job current_user, collection, params[:columns].values
-
render json: :ok
-
end
-
end
-
-
1
def import_in_progress
-
redirect_to import_finished_collection_import_wizard_path(collection) if import_job.status_finished?
-
-
add_breadcrumb I18n.t('views.collections.tab.import_wizard'), collection_import_wizard_path(collection)
-
end
-
-
1
def import_finished
-
add_breadcrumb I18n.t('views.collections.tab.import_wizard'), collection_import_wizard_path(collection)
-
end
-
-
1
def import_failed
-
add_breadcrumb I18n.t('views.collections.tab.import_wizard'), collection_import_wizard_path(collection)
-
end
-
-
1
def cancel_pending_jobs
-
ImportWizard.cancel_pending_jobs(current_user, collection)
-
flash[:notice] = I18n.t('views.import_wizards.import_canceled')
-
redirect_to collection_import_wizard_path
-
end
-
-
1
def job_status
-
render json: {:status => import_job.status}
-
end
-
-
1
def logs
-
add_breadcrumb I18n.t('views.collections.tab.import_wizard'), collection_import_wizard_path(collection)
-
end
-
end
-
1
class LayersController < ApplicationController
-
1
before_filter :authenticate_user!
-
1
before_filter :authenticate_collection_admin!, :except => [:index]
-
1
before_filter :fix_field_config, only: [:create, :update]
-
-
1
def index
-
layers # signal that layers will be used on this page (loaded by ajax later)
-
respond_to do |format|
-
format.html do
-
show_collection_breadcrumb
-
add_breadcrumb "Properties", collection_path(collection)
-
add_breadcrumb "Layers", collection_layers_path(collection)
-
end
-
format.json { render_json collection.layers_to_json(current_user_snapshot.at_present?, current_user) }
-
end
-
end
-
-
1
def create
-
2
layer = layers.new params[:layer]
-
2
layer.collection_id = params[:collection_id]
-
2
layer.user = current_user
-
2
layer.save!
-
2
current_user.layer_count += 1
-
2
current_user.update_successful_outcome_status
-
2
current_user.save!(:validate => false)
-
2
render json: layer.as_json(include: :fields)
-
end
-
-
1
def update
-
# FIX: For some reason using the exposed layer here results in duplicated fields being created
-
1
layer = collection.layers.find params[:id]
-
1
fix_layer_fields_for_update layer
-
1
layer.user = current_user
-
1
layer.update_attributes! params[:layer]
-
1
layer.reload
-
1
render json: layer.as_json(include: :fields)
-
end
-
-
1
def set_order
-
layer.user = current_user
-
layer.update_attributes! ord: params[:ord]
-
render json: layer
-
end
-
-
1
def destroy
-
-
if params['threshold_ids']
-
Threshold.delete(params['threshold_ids'])
-
collection.recreate_index
-
end
-
-
layer.user = current_user
-
layer.destroy
-
head :ok
-
end
-
-
1
def upload_layers
-
path = File.join('public', 'tmp_layers.json')
-
content = params[:file].read
-
File.open(path, "wb") { |f| f.write(content) }
-
begin
-
layers = JSON.parse content
-
flash[:notice] = "File uploaded"
-
redirect_to :action => "adjust_layers"
-
rescue Exception => e
-
flash[:alert] = "Invalid file content"
-
redirect_to :action => "index"
-
end
-
-
end
-
-
1
def adjust_layers
-
show_collection_breadcrumb
-
add_breadcrumb I18n.t('views.collections.index.properties'), collection_path(collection)
-
add_breadcrumb I18n.t('views.collections.tab.layers'), collection_layers_path(collection)
-
end
-
-
1
def pending_layers
-
path = File.join('public', 'tmp_layers.json')
-
all_new_layers = []
-
if File.exist?(path)
-
raw_layers = File.read(path, :encoding => 'utf-8')
-
all_layers = JSON.parse raw_layers
-
File.delete(path)
-
all_layers.each do |l|
-
result = layer.decode_raw_layer l
-
new_layer = layers.new result
-
new_layer.user = current_user
-
all_new_layers.push(new_layer.as_json(include: :fields.as_json(:except => [:id]), :except => [:id, :ord]))
-
end
-
end
-
render json: all_new_layers
-
end
-
-
1
private
-
-
# The options come as a hash insted of a list, so we convert the hash to a list
-
# Also fix hierarchy in the same way.
-
1
def fix_field_config
-
3
if params[:layer] && params[:layer][:fields_attributes]
-
2
params[:layer][:fields_attributes].each do |field_idx, field|
-
-
-
2
if field[:config]
-
1
if field[:config][:locations]
-
1
field[:config][:locations] = field[:config][:locations].values
-
end
-
1
if field[:config][:options]
-
field[:config][:options] = field[:config][:options].values
-
field[:config][:options].each { |option| option['id'] = option['id'].to_i }
-
end
-
1
field[:config][:next_id] = field[:config][:next_id].to_i if field[:config][:next_id]
-
1
if field[:config][:hierarchy]
-
field[:config][:hierarchy] = field[:config][:hierarchy].values
-
sanitize_items field[:config][:hierarchy]
-
end
-
-
1
if field[:is_enable_field_logic] == "false"
-
1
params[:layer][:fields_attributes][field_idx][:config] = params[:layer][:fields_attributes][field_idx][:config].except(:field_logics)
-
end
-
-
1
if field[:config][:field_logics]
-
field[:config][:field_logics] = field[:config][:field_logics].values
-
field[:config][:field_logics].each { |field_logic|
-
field_logic['id'] = field_logic['id'].to_i
-
field_logic['value'] = field_logic['value'].to_i
-
if field_logic['field_id']
-
-
if field_logic['field_id'] == ""
-
field_logic['field_id'] = nil
-
end
-
end
-
}
-
end
-
-
1
field[:config][:range] = fix_field_config_range(field_idx, field) if field[:is_enable_range]
-
-
end
-
end
-
end
-
end
-
-
1
def fix_field_config_range(field_idx,field)
-
if field[:is_enable_range] == "false"
-
params[:layer][:fields_attributes][field_idx][:config] = params[:layer][:fields_attributes][field_idx][:config].except(:range)
-
else
-
if field[:config][:range]
-
if field[:config][:range][:minimum] == "" || field[:config][:range][:minimum].nil?
-
field[:config][:range] = field[:config][:range].except(:minimum)
-
else
-
field[:config][:range][:minimum] = field[:config][:range][:minimum].to_f
-
end
-
if field[:config][:range][:maximum] == "" || field[:config][:range][:maximum].nil?
-
field[:config][:range] = field[:config][:range].except(:maximum)
-
else
-
field[:config][:range][:maximum] = field[:config][:range][:maximum].to_f
-
end
-
end
-
end
-
return field[:config][:range]
-
end
-
-
1
def validate_field_logic
-
field[:config][:field_logics].delete_if { |field_logic| !field_logic['layer_id'] }
-
if field[:config][:field_logics].length == 0
-
params[:layer][:fields_attributes][field_idx][:config] = params[:layer][:fields_attributes][field_idx][:config].except(:field_logics)
-
end
-
end
-
-
1
def sanitize_items(items)
-
items.each do |item|
-
if item[:sub]
-
item[:sub] = item[:sub].values
-
sanitize_items item[:sub]
-
end
-
end
-
end
-
-
# Instead of sending the _destroy flag to destroy fields (complicates things on the client side code)
-
# we check which are the current fields ids, which are the new ones and we delete those fields
-
# whose ids don't show up in the new ones and then we add the _destroy flag.
-
#
-
# That way we preserve existing fields and we can know if their codes change, to trigger a reindex
-
1
def fix_layer_fields_for_update layer
-
1
fields = layer.fields
-
-
1
fields_ids = fields.map(&:id).compact
-
2
new_ids = params[:layer][:fields_attributes].values.map { |x| x[:id].try(:to_i) }.compact
-
1
removed_fields_ids = fields_ids - new_ids
-
-
1
max_key = params[:layer][:fields_attributes].keys.map(&:to_i).max
-
1
max_key += 1
-
-
1
removed_fields_ids.each do |id|
-
params[:layer][:fields_attributes][max_key.to_s] = {id: id, _destroy: true}
-
max_key += 1
-
end
-
-
1
params[:layer][:fields_attributes] = params[:layer][:fields_attributes].values
-
end
-
-
1
def get_associated_field_threshold_ids(field)
-
associated_field_threshold_ids = []
-
fieldID = field["id"]
-
-
self.collection.thresholds.map { |threshold|
-
threshold.conditions.map { |condition|
-
conditionFieldID = condition['field'].to_i
-
if fieldID == conditionFieldID
-
associated_field_threshold_ids.push(threshold.id)
-
break
-
end
-
}
-
}
-
-
associated_field_threshold_ids
-
end
-
-
end
-
1
class MembershipsController < ApplicationController
-
1
before_filter :authenticate_user!
-
1
before_filter :authenticate_collection_admin!, :only => [:create, :set_layer_access, :set_admin, :unset_admin, :index]
-
-
1
include ApplicationHelper
-
-
1
def index
-
layer_memberships = collection.layer_memberships.all.inject({}) do |hash, membership|
-
(hash[membership.user_id] ||= []) << membership
-
hash
-
end
-
memberships = collection.memberships.includes([:user, :read_sites_permission, :write_sites_permission]).all.map do |membership|
-
user_display_name = User.generate_user_display_name membership.user
-
if user_display_name == membership.user.phone_number
-
user_phone_number = ""
-
else
-
user_phone_number = membership.user.phone_number
-
end
-
-
{
-
user_id: membership.user_id,
-
user_display_name: user_display_name,
-
user_phone_number: user_phone_number,
-
admin: membership.admin?,
-
layers: (layer_memberships[membership.user_id] || []).map{|x| {layer_id: x.layer_id, read: x.read?, write: x.write?}},
-
sites: {
-
none: membership.none_sites_permission,
-
read: membership.read_sites_permission,
-
write: membership.write_sites_permission
-
}
-
}
-
end
-
render json: memberships, :root => false
-
end
-
-
1
def create
-
user = User.find_by_email params[:email]
-
if user && !user.memberships.where(:collection_id => collection.id).exists?
-
user.memberships.create! :collection_id => collection.id
-
render json: {status: :added, user_id: user.id, user_display_name: user.display_name}
-
else
-
register_new_member
-
#render json: {status: :not_added}
-
end
-
end
-
-
1
def invitable
-
users = User.
-
where('email LIKE ?', "#{params[:term]}%").
-
where("id not in (?)", collection.memberships.pluck(:user_id)).
-
order('email')
-
render json: users.pluck(:email), :root => false
-
end
-
-
1
def search
-
3
users = User.
-
where('email LIKE ?', "#{params[:term]}%").
-
where("id in (?)", collection.memberships.pluck(:user_id)).
-
order('email')
-
-
3
render json: users.pluck(:email), :root => false
-
end
-
-
1
def destroy
-
membership = collection.memberships.find_by_user_id params[:id]
-
if leave_collection_permission? || membership.user_id != current_user.id
-
membership.destroy
-
end
-
redirect_to collections_path
-
end
-
-
1
def set_layer_access
-
membership = collection.memberships.find_by_user_id params[:id]
-
membership.set_layer_access params
-
render json: :ok
-
end
-
-
1
def set_admin
-
change_admin_flag true
-
end
-
-
1
def unset_admin
-
change_admin_flag false
-
end
-
-
1
def register_new_member
-
if (params[:user][:email].strip.length == 0)
-
params[:user][:email] = User.generate_default_email
-
end
-
-
params[:user][:password] = User.generate_random_password if params[:user]
-
if (User.find_all_by_phone_number(params[:user][:phone_number]).count == 0)
-
user = User.create params[:user] if params[:user]
-
user.confirmed_at = Time.now
-
if user.save!
-
user = User.find_by_email params[:user][:email]
-
user.memberships.create! admin: false, user_id: user.id, collection_id: collection.id
-
membership = collection.memberships.find_by_user_id user.id
-
user_display_name = User.generate_user_display_name user
-
if membership
-
collection.layers.each do |l|
-
membership.set_layer_access :access => true, :layer_id => l.id, :verb => "read"
-
end
-
end
-
layer_memberships = collection.layer_memberships.all.inject({}) do |hash, membership|
-
(hash[membership.user_id] ||= []) << membership
-
hash
-
end
-
render json: {
-
status: :ok,
-
user_id: user.id,
-
layers: (layer_memberships[membership.user_id] || []).map{|x| {layer_id: x.layer_id, read: x.read?, write: x.write?}},
-
user_display_name: user_display_name
-
}
-
else
-
render json: :unsaved
-
end
-
else
-
render json: {status: :phone_existed}
-
end
-
end
-
-
1
private
-
-
1
def change_admin_flag(new_value)
-
membership = collection.memberships.find_by_user_id params[:id]
-
membership.admin = new_value
-
membership.save!
-
-
render json: :ok
-
end
-
end
-
1
require 'treetop_dependencies'
-
1
require 'digest'
-
-
1
class NuntiumController < ApplicationController
-
1
helper_method :save_message
-
1
protect_from_forgery :except => :receive
-
1
before_filter :set_timezone, :except => [:receive, :authenticate]
-
-
1
USER_NAME, PASSWORD = 'iLab', '1c4989610bce6c4879c01bb65a45ad43'
-
-
# POST /messaging
-
# def index
-
# raise HttpVerbNotSupported.new unless request.post?
-
# message = save_message
-
# begin
-
# message.process! params
-
# rescue => err
-
# message.reply = err.message
-
# ensure
-
# if (message.reply != "Invalid command")
-
# message[:collection_id] = get_collection_id(params[:body])
-
# end
-
# message.save
-
# render :text => message.reply, :content_type => "text/plain"
-
# end
-
# end
-
-
# POST /nuntium
-
1
def receive
-
7
begin
-
7
message = save_message
-
rescue => err
-
4
render :text => err.message, :status => 400
-
4
return
-
end
-
-
3
begin
-
3
message.process! params
-
rescue => err
-
message.reply = err.message
-
ensure
-
3
if (message.reply != "Invalid command")
-
3
collection_id = get_collection_id(params[:body])
-
3
if collection_id and collection_id >0
-
3
message[:collection_id] = collection_id
-
end
-
end
-
3
message.save
-
3
render :text => message.reply, :content_type => "text/plain"
-
3
end
-
end
-
-
1
def authenticate
-
2
authenticate_or_request_with_http_basic 'Dynamic Resource Map - HTTP' do |username, password|
-
1
USER_NAME == username && PASSWORD == Digest::MD5.hexdigest(password)
-
end
-
end
-
-
1
def get_collection_id(bodyMsg)
-
3
if (bodyMsg[5] == "q")
-
collectionId = Message.getCollectionId(bodyMsg, 7)
-
3
elsif (bodyMsg[5] == "u")
-
3
siteCode = Message.getCollectionId(bodyMsg, 7)
-
3
site = Site.find_by_id_with_prefix(siteCode)
-
3
if site
-
3
collectionId = site.collection_id
-
else
-
collectionId = -1
-
end
-
end
-
3
return collectionId
-
end
-
-
1
def save_message
-
5
Message.create!(:guid => params[:guid], :from => params[:from], :body => params[:body]) do |m|
-
4
m.country = params[:country]
-
4
m.carrier = params[:carrier]
-
4
m.channel = params[:channel]
-
4
m.application = params[:application]
-
4
m.to = params[:to]
-
end
-
end
-
end
-
1
class QuotasController < ApplicationController
-
1
before_filter :authenticate_user!
-
1
def index
-
@collections = Collection.all
-
end
-
-
1
def create
-
1
collection = Collection.find params["collection_id"]
-
1
collection.quota = collection.quota + params["quota"].to_i
-
1
collection.save!
-
1
redirect_to quotas_path
-
end
-
-
1
def show
-
1
collection = Collection.find params["id"]
-
1
render :json => collection
-
end
-
end
-
1
class SitesController < ApplicationController
-
25
before_filter :setup_guest_user, :if => Proc.new { collection && collection.public }
-
25
before_filter :authenticate_user!, :except => [:index, :search, :search_alert_site], :unless => Proc.new { collection && collection.public }
-
-
1
authorize_resource :only => [:index, :search, :search_alert_site], :decent_exposure => true
-
-
1
expose(:sites) {if !current_user_snapshot.at_present? && collection then collection.site_histories.at_date(current_user_snapshot.snapshot.date) else collection.sites end}
-
12
expose(:site) { Site.find(params[:site_id] || params[:id]) }
-
-
1
def index
-
search = new_search
-
-
search.name_start_with params[:name] if params[:name].present?
-
search.alerted_search params[:_alert] if params[:_alert] == "true"
-
search.offset params[:offset] if params[:offset].present?
-
search.limit params[:limit] if params[:limit].present?
-
-
#hierarchy mode display
-
if !(params[:limit] && params[:offset])
-
search.unlimited
-
end
-
-
render json: search.ui_results.map { |x| x['_source'] }, :root => false
-
end
-
-
1
def show
-
search = new_search
-
-
search.id params[:id]
-
# If site does not exists, return empty objects
-
result = search.ui_results.first['_source'] rescue {}
-
-
render json: result
-
end
-
-
1
def create
-
2
site_params = JSON.parse params[:site]
-
2
ui_attributes = prepare_from_ui(site_params)
-
2
site = collection.sites.new(ui_attributes.merge(user: current_user))
-
2
if site.valid?
-
2
site.save!
-
2
current_user.site_count += 1
-
2
current_user.update_successful_outcome_status
-
2
current_user.save!(:validate => false)
-
2
render json: site, :layout => false
-
else
-
render json: site.errors.messages, status: :unprocessable_entity, :layout => false
-
end
-
end
-
-
1
def update
-
2
site_params = JSON.parse params[:site]
-
2
site.user = current_user
-
2
site.properties_will_change!
-
2
site.attributes = prepare_from_ui(site_params)
-
2
if site.valid?
-
2
site.save!
-
2
if params[:photosToRemove]
-
Site::UploadUtils.purgePhotos(params[:photosToRemove])
-
end
-
2
render json: site, :layout => false
-
else
-
render json: site.errors.messages, status: :unprocessable_entity, :layout => false
-
end
-
end
-
-
1
def update_property
-
19
field = site.collection.fields.where_es_code_is params[:es_code]
-
19
if not site.collection.site_ids_permission(current_user).include? site.id
-
19
return head :forbidden unless current_user.can_write_field? field, site.collection, params[:es_code]
-
end
-
-
19
site.user = current_user
-
19
site.properties_will_change!
-
-
19
site.properties[params[:es_code]] = field.decode_from_ui(params[:value])
-
19
if site.valid?
-
10
site.save!
-
10
render json: site, :status => 200, :layout => false
-
else
-
9
error_message = site.errors[:properties][0][params[:es_code]]
-
9
render json: {:error_message => error_message}, status: :unprocessable_entity, :layout => false
-
end
-
end
-
-
1
def search
-
zoom = params[:z].to_i
-
-
if params[:collection_ids].is_a? String
-
collection_ids_array = params[:collection_ids].split ","
-
elsif params[:collection_ids].is_a? Array
-
collection_ids_array = params[:collection_ids]
-
end
-
-
search = MapSearch.new collection_ids_array, user: current_user
-
-
search.zoom = zoom
-
search.bounds = params if zoom >= 2
-
search.exclude_id params[:exclude_id].to_i if params[:exclude_id].present?
-
search.after params[:updated_since] if params[:updated_since]
-
search.full_text_search params[:search] if params[:search].present?
-
search.alerted_search params[:_alert] if params[:_alert].present?
-
search.location_missing if params[:location_missing].present?
-
search.name_search params[:sitename] if params[:sitename].present?
-
search.hierarchy_mode params[:selected_site_children] if params[:selected_site_parent].present?
-
if params[:selected_hierarchies].present?
-
search.selected_hierarchy params[:hierarchy_code], params[:selected_hierarchies]
-
end
-
search.where params.except(:selected_site_children, :selected_site_parent, :action,
-
:controller, :format, :n, :s, :e, :w, :z, :collection_ids, :exclude_id,
-
:updated_since, :search, :location_missing, :hierarchy_code,
-
:selected_hierarchies, :_alert)
-
-
render_json search.results, :root => false
-
end
-
-
1
def search_alert_site
-
zoom = params[:z].to_i
-
-
search = MapSearch.new params[:collection_ids], user: current_user
-
-
search.zoom = zoom
-
search.bounds = params if zoom >= 2
-
search.exclude_id params[:exclude_id].to_i if params[:exclude_id].present?
-
search.after params[:updated_since] if params[:updated_since]
-
search.full_text_search params[:search] if params[:search].present?
-
search.alerted_search params[:_alert] if params[:_alert].present?
-
search.location_missing if params[:location_missing].present?
-
if params[:selected_hierarchies].present?
-
search.selected_hierarchy params[:hierarchy_code], params[:selected_hierarchies]
-
end
-
search.where params.except(:selected_site_children, :selected_site_parent, :action, :controller, :format, :n, :s, :e, :w, :z, :collection_ids, :exclude_id, :updated_since, :search, :location_missing, :hierarchy_code, :selected_hierarchies, :_alert)
-
-
# search.apply_queries
-
# render json: search.sites_json
-
render_json search.sites_json, :root => false
-
end
-
-
1
def destroy
-
1
site.user = current_user
-
1
Site::UploadUtils.purgeUploadedPhotos(site)
-
1
site.destroy
-
1
render json: site, :root => false
-
end
-
-
1
def visible_layers_for
-
layers = []
-
if site.collection.site_ids_permission(current_user).include? site.id
-
target_fields = fields.includes(:layer).all
-
layers = target_fields.map(&:layer).uniq.map do |layer|
-
{
-
id: layer.id,
-
name: layer.name,
-
ord: layer.ord,
-
}
-
end
-
if site.collection.site_ids_write_permission(current_user).include? site.id
-
layers.each do |layer|
-
layer[:fields] = target_fields.select { |field| field.layer_id == layer[:id] }
-
layer[:fields].map! do |field|
-
{
-
id: field.es_code,
-
name: field.name,
-
code: field.code,
-
kind: field.kind,
-
config: field.config,
-
ord: field.ord,
-
writeable: true
-
}
-
end
-
end
-
elsif site.collection.site_ids_read_permission(current_user).include? site.id
-
layers.each do |layer|
-
layer[:fields] = target_fields.select { |field| field.layer_id == layer[:id] }
-
layer[:fields].map! do |field|
-
{
-
id: field.es_code,
-
name: field.name,
-
code: field.code,
-
kind: field.kind,
-
config: field.config,
-
ord: field.ord,
-
writeable: false
-
}
-
end
-
end
-
end
-
layers.sort! { |x, y| x[:ord] <=> y[:ord] }
-
else
-
layers = site.collection.visible_layers_for(current_user)
-
end
-
render json: layers, :root => false
-
end
-
-
1
private
-
-
1
def prepare_from_ui(parameters)
-
4
fields = collection.fields.index_by(&:es_code)
-
4
decoded_properties = {}
-
4
site_properties = parameters.delete("properties") || {}
-
4
files = params[:fileUpload] || {}
-
-
4
site_properties.each_pair do |es_code, value|
-
10
value = [ value, files[value] ] if fields[es_code].kind == 'photo'
-
10
decoded_properties[es_code] = fields[es_code].decode_from_ui(value)
-
end
-
-
4
parameters["properties"] = decoded_properties unless decoded_properties.blank?
-
4
parameters
-
end
-
end
-
1
class SitesPermissionController < ApplicationController
-
1
before_filter :authenticate_user!
-
1
before_filter :authenticate_collection_admin!, only: :create
-
-
6
before_filter :setup_guest_user, :if => Proc.new { collection && collection.public }
-
6
before_filter :authenticate_user!, :unless => Proc.new { collection && collection.public }
-
-
1
def index
-
8
membership = current_user.memberships.find{|m| m.collection_id == params[:collection_id].to_i}
-
4
render json: membership.try(:sites_permission) || SitesPermission.no_permission
-
end
-
-
1
def create
-
1
membership = collection.memberships.find_by_user_id params[:sites_permission].delete :user_id
-
1
membership.update_sites_permission params[:sites_permission]
-
-
1
render json: :ok
-
end
-
end
-
1
module Api::GeoJsonHelper
-
1
def collection_geo_json(collection, results)
-
root = {}
-
root[:type] = 'Feature'
-
root[:geometry] = nil
-
root[:properties] = (props = {features: (features = {})})
-
-
props[:name] = collection.name
-
props[:previousPage] = url_for(params.merge page: results.previous_page, only_path: false) if results.previous_page
-
props[:nextPage] = url_for(params.merge page: results.next_page, only_path: false) if results.next_page
-
props[:count] = results.total
-
props[:totalPages] = results.total_pages
-
-
features[:type] = 'FeatureCollection'
-
features[:features] = results.map { |result| site_item_geo_json result }
-
-
root
-
end
-
-
1
def site_item_geo_json(result)
-
source = result['_source']
-
-
obj = {}
-
obj[:type] = 'Feature'
-
obj[:geometry] = {type: 'Point', coordinates: [source['location']['lon'], source['location']['lat']]}
-
obj[:id] = source['id']
-
obj[:properties] = (props = {})
-
-
props[:name] = source['name']
-
props[:createdAt] = Site.parse_time(source['created_at'])
-
props[:updatedAt] = Site.parse_time(source['updated_at'])
-
props[:properties] = source['properties']
-
-
obj
-
end
-
end
-
-
1
module Api::JsonHelper
-
1
def collection_json(collection, results)
-
4
obj = {}
-
4
obj[:id] = collection.id
-
4
obj[:name] = collection.name
-
4
obj[:is_visible_location] = collection.is_visible_location
-
4
obj[:is_visible_name] = collection.is_visible_name
-
4
obj[:previousPage] = url_for(params.merge page: results.previous_page, only_path: false) if results.previous_page
-
4
obj[:nextPage] = url_for(params.merge page: results.next_page, only_path: false) if results.next_page
-
4
obj[:count] = results.total
-
4
obj[:totalPages] = results.total_pages
-
10
obj[:sites] = results.map {|result| site_item_json result}
-
4
obj
-
end
-
-
1
def site_item_json(result)
-
6
source = result['_source']
-
-
6
obj = {}
-
6
obj[:id] = source['id']
-
6
obj[:name] = source['name']
-
6
obj[:createdAt] = Site.parse_time(source['created_at'])
-
6
obj[:updatedAt] = Site.parse_time(source['updated_at'])
-
-
6
if source['location']
-
6
obj[:lat] = source['location']['lat']
-
6
obj[:long] = source['location']['lon']
-
end
-
-
6
source['properties'].each do |key, property|
-
30
field = Field.find_by_code(key)
-
30
if field.kind == 'photo'
-
source['properties'][key] = "#{Settings.host}/photo_field/#{property}"
-
break
-
end
-
end
-
-
6
obj[:properties] = source['properties']
-
-
6
obj
-
end
-
end
-
1
module Api::RssHelper
-
1
def collection_rss(xml, collection, results)
-
2
xml.rss rss_specification do
-
2
xml.channel do
-
2
xml.title collection.name
-
2
xml.lastBuildDate collection.updated_at.rfc822
-
2
xml.atom :link, rel: :previous, href: url_for(params.merge page: results.previous_page, only_path: false) if results.previous_page
-
2
xml.atom :link, rel: :next, href: url_for(params.merge page: results.next_page, only_path: false) if results.next_page
-
-
2
results.each do |result|
-
4
site_item_rss xml, result
-
end
-
end
-
end
-
end
-
-
1
def site_item_rss(xml, result)
-
4
source = result['_source']
-
-
4
xml.item do
-
4
xml.title source['name']
-
4
xml.pubDate Site.parse_time(source['updated_at']).rfc822
-
4
xml.link api_site_url(source['id'], format: :rss)
-
4
xml.guid api_site_url(source['id'], format: :rss)
-
-
4
if source['location']
-
4
xml.geo :lat, source['location']['lat']
-
4
xml.geo :long, source['location']['lon']
-
end
-
-
4
xml.rm :properties do
-
4
source['properties'].each do |code, values|
-
20
values = Array(values)
-
20
if(values.count == 1)
-
18
property_rss xml, code, values.first
-
else
-
2
xml.rm code.to_sym do
-
2
values.each do |value|
-
4
xml.rm :option, code: value
-
end
-
end
-
end
-
end
-
end
-
end
-
end
-
-
1
def activities_rss(xml, activities)
-
xml.rss rss_specification do
-
xml.channel do
-
xml.title 'Activity'
-
xml.lastBuildDate activities.first.created_at.rfc822 if activities.length > 0
-
xml.atom :link, rel: :previous, href: url_for(params.merge page: @page - 1, only_path: false) if @page > 1
-
xml.atom :link, rel: :next, href: url_for(params.merge page: @page + 1, only_path: false) if @hasNextPage
-
-
activities.each do |activity|
-
activity_rss xml, activity
-
end
-
end
-
end
-
end
-
-
1
def activity_rss(xml, activity)
-
xml.item do
-
xml.title "[In collection '#{activity.collection.name}' by user '#{activity.user.display_name}'] #{activity.description} "
-
xml.pubDate activity.created_at.rfc822
-
xml.guid activity.id
-
xml.rm :collection, activity.collection.name
-
xml.rm :itemtype, activity.item_type
-
xml.rm :itemid, activity.item_id
-
xml.rm :action, activity.action
-
xml.rm :user, activity.user.display_name
-
end
-
end
-
-
1
def rss_specification
-
{
-
'version' => "2.0",
-
'xmlns:geo' => "http://www.w3.org/2003/01/geo/wgs84_pos#",
-
'xmlns:rm' => "http://resourcemap.instedd.org/api/1.0",
-
'xmlns:atom' => "http://www.w3.org/2005/Atom"
-
2
}
-
end
-
-
1
private
-
-
1
def property_rss(xml, code, value)
-
18
xml.__send__ "rm:#{code}", value
-
end
-
end
-
1
module ApplicationHelper
-
1
include KnockoutHelper
-
-
1
def google_maps_javascript_include_tag
-
2
javascript_include_tag(raw("#{Settings.protocol}://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false&key=#{GoogleMapsKey}&v=3.9"))
-
end
-
-
1
def leave_collection_permission?
-
flag = false
-
if !collection_admin? || collection.get_number_of_admin_membership > 1
-
flag = true
-
end
-
flag
-
end
-
-
1
def collection_admin?
-
@collection_admin = current_user.admins?(collection) if @collection_admin.nil?
-
@collection_admin
-
end
-
-
1
def render_plugin_hook(plugin, name, args = {})
-
8
result = ''
-
8
plugin.hooks[name].each do |view|
-
2
result << render(view, args)
-
end
-
8
result.html_safe
-
end
-
-
1
def render_hook(collection, name, args = {})
-
result = ''
-
collection.each_plugin do |plugin|
-
result << render_plugin_hook(plugin, name, args)
-
end
-
result.html_safe
-
end
-
-
1
def field_edit_view(kind)
-
56
Field::plugin_kinds.has_key?(kind) ? Field::plugin_kinds[kind][:edit_view] : "collections/fields/#{kind}_edit_view"
-
end
-
-
1
def show_language_options
-
8
languages = Language.all.map do |language|
-
link_to language.name, 'javascript:void(0);', data: {locale: language.code}, style: 'font-size:12px;'
-
end
-
8
languages.join(' | ').html_safe
-
end
-
end
-
1
module ChannelsAccessesHelper
-
end
-
1
module KnockoutHelper
-
1
def ko_link_to(text, click, options = {})
-
6
link_to text, 'javascript:void()', options.merge(ko click: click)
-
end
-
-
1
def ko_link_to_root(text, click, options = {})
-
ko_link_to text, "$root.#{click}", options
-
end
-
-
1
def ko_text_field_tag(name, options = {})
-
16
html_opts = options.delete(:html)
-
16
text_field_tag name, '', ko(options.reverse_merge(value: name, valueUpdate: :afterkeydown)).merge(html_opts || {})
-
end
-
-
1
def ko_text_area_tag(name, options = {})
-
4
html_opts = options.delete(:html)
-
4
text_area_tag name, '', ko(options.reverse_merge(value: name, valueUpdate: :afterkeydown)).merge(html_opts || {})
-
end
-
-
1
def ko_number_field_tag(name, options = {})
-
html_opts = options.delete(:html)
-
number_field_tag name, '', ko(options.reverse_merge(value: name, valueUpdate: :afterkeydown)).merge(html_opts || {})
-
end
-
-
1
def ko_html_field_tag(name, options = {})
-
4
html_opts = options.delete(:html)
-
4
text_field_tag name, '', ko(options.reverse_merge(value: name, valueUpdate: :afterkeydown)).merge(html_opts || {})
-
end
-
-
1
def ko_check_box_tag(name, options = {})
-
check_box_tag name, '1', false, options.reverse_merge(ko checked: name)
-
end
-
-
1
def ko_radio_button_tag(name, value, options = {})
-
radio_button_tag name, value, false, options.reverse_merge(ko checked: name)
-
end
-
-
1
def ko(hash = {})
-
474
{'data-bind' => kov(hash)}
-
end
-
-
1
def kov(hash = {})
-
hash.map do |k, v|
-
1132
if v.respond_to? :to_hash
-
224
"#{k}:{#{kov(v)}}"
-
elsif k.to_s == 'valueUpdate'
-
52
"#{k}:'#{v}'"
-
else
-
856
"#{k}:#{v}"
-
end
-
704
end.join(',')
-
end
-
end
-
1
module QuotasHelper
-
end
-
1
module RegistrationsHelper
-
1
def resource_name
-
:user
-
end
-
-
1
def resource
-
@resource ||= User.new
-
end
-
-
1
def devise_mapping
-
@devise_mapping ||= Devise.mappings[:user]
-
end
-
end
-
1
class SendMailer < ActionMailer::Base
-
1
default from: "noreply@resourcemap.instedd.org"
-
-
1
def notify_email(users_email, message, email_subject)
-
3
mail(:to => users_email, :subject => email_subject) do |format|
-
6
format.text {render :text => message}
-
end
-
end
-
end
-
1
class Ability
-
1
include CanCan::Ability
-
-
1
def initialize(user, format = nil)
-
-
108
user ||= User.new :is_guest => true
-
-
### Collection ###
-
-
# Admin abilities
-
108
can [:destroy, :create_snapshot, :recreate_index, :update, :members,:send_new_member_sms, :register_gateways, :export], Collection, :memberships => { :user_id => user.id , :admin => true }
-
108
can :manage, Snapshot, :collection => {:memberships => { :user_id => user.id , :admin => true } }
-
-
# User can read collection if she is a collection member or if the collection is public
-
108
can [:read, :sites_by_term, :search, :sites_info, :alerted_collections, :register_gateways], Collection, :memberships => { :user_id => user.id }
-
108
can [:read, :sites_by_term, :search, :sites_info, :alerted_collections, :register_gateways], Collection, :public => true
-
-
108
can [:search, :index, :search_alert_site], Site, :collection => {:public => true}
-
108
can [:search, :index, :search_alert_site], Site, :collection => {:memberships => { :user_id => user.id }}
-
108
can :delete, Site, :collection => {:memberships => { :user_id => user.id , :admin => true } }
-
-
108
if !user.is_guest
-
82
can [:new, :create], Collection
-
end
-
-
# Member Abilities
-
108
can [:csv_template, :upload_csv, :unload_current_snapshot, :load_snapshot, :register_gateways, :message_quota, :reminders, :settings, :quotas], Collection, :memberships => { :user_id => user.id }
-
-
# In progress
-
108
can :max_value_of_property, Collection, :memberships => { :user_id => user.id }
-
108
can :decode_hierarchy_csv, Collection, :memberships => { :user_id => user.id }
-
108
can :decode_location_csv, Collection, :memberships => { :user_id => user.id }
-
108
can :download_location_csv, Collection, :memberships => { :user_id => user.id }
-
-
-
#Move from InSTEDD RM
-
108
can :update_site_property, Field do |field, site|
-
if user.is_guest
-
false
-
else
-
collection = field.collection
-
membership = Membership.where("user_id = ? and collection_id = ?", user.id, collection.id).first
-
-
if membership
-
admin = membership.try(:admin?)
-
lm = LayerMembership.where("user_id = ? and collection_id = ? and layer_id = ?",user.id,collection.id,field.layer_id).first
-
# lm = membership.layer_memberships.find{|layer_membership| layer_membership.layer_id == field.layer_id}
-
admin || (lm && lm.write)
-
else
-
false
-
end
-
end
-
end
-
-
# Full update, only admins have rights to do this
-
108
can :update, Site, :collection => { :memberships => { :user_id => user.id, :admin => true } }
-
-
108
can :update_name, Membership do |user_membership|
-
user_membership.can_update?("name")
-
end
-
-
108
can :update_location, Membership do |user_membership|
-
user_membership.can_update?("location")
-
end
-
-
end
-
end
-
#encoding: UTF-8
-
1
require "csv"
-
-
1
class Activity < ActiveRecord::Base
-
1
ItemTypesAndActions = {
-
'collection' => %w(created imported csv_imported deleted),
-
'layer' => %w(created changed deleted),
-
'site' => %w(created changed deleted)
-
}
-
14
Kinds = Activity::ItemTypesAndActions.map { |item_type, actions| actions.map { |action| "#{item_type},#{action}" } }.flatten.freeze
-
-
1
belongs_to :collection
-
1
belongs_to :user
-
1
belongs_to :layer
-
1
belongs_to :field
-
1
belongs_to :site
-
-
1
serialize :data, MarshalZipSerializable
-
-
1
validates_inclusion_of :item_type, :in => ItemTypesAndActions.keys
-
1
before_save :set_log_by_reference_column_value
-
1
before_save :set_user_email
-
1
before_save :set_collection_name
-
-
1
def set_collection_name
-
1727
self.collection_name = collection.name unless collection.nil?
-
end
-
-
1
def set_user_email
-
1727
self.user_email = user.email unless user.nil?
-
end
-
-
1
def set_log_by_reference_column_value
-
1727
self.log = description
-
end
-
-
1
def self.filter user, options=nil
-
#index with default options
-
current_user = user
-
acts = Activity.order('id desc').includes(:collection, :site, :user)
-
result = []
-
unless options
-
acts_with_collection = acts.where(collection_id: current_user.memberships.pluck(:collection_id))
-
acts_with_deleted_collection = acts.where(collection_id: nil, user_id: current_user.id)
-
result = acts_with_collection + acts_with_deleted_collection
-
end
-
-
-
#filter
-
if options
-
if options[:collection_ids]
-
acts_with_collection = acts.where(collection_id: options[:collection_ids])
-
result = acts_with_collection
-
end
-
-
if options[:deleted_collection] == "true"
-
acts_with_deleted_collection = acts.where(collection_id: nil, user_id: current_user.id)
-
result = result + acts_with_deleted_collection
-
end
-
end
-
-
result
-
end
-
-
1
def self.migrate_columns_to_log
-
Activity.transaction do
-
Activity.find_each(batch_size: 100) do |activity|
-
activity.log = activity.description
-
activity.save
-
end
-
end
-
end
-
-
1
def self.search_collection options
-
activities = Activity.order('id desc' ).includes(:site, :user, :collection, :field)
-
-
activities = activities.where(["collection_id = :collection_id",
-
:collection_id => options[:id]
-
])
-
-
activities = activities.where(' item_type = "site" ')
-
-
case options[:type]
-
-
when "month"
-
current_month = DateTime.current.beginning_of_month
-
activities = activities.where("created_at >= :current_month ", :current_month => current_month)
-
-
when "previous_month"
-
previous_month = DateTime.current - 1.month
-
start_day = previous_month.beginning_of_month.beginning_of_day
-
end_day = previous_month.end_of_month.end_of_day
-
activities = activities.where(['created_at BETWEEN :start_day AND :end_day',
-
:start_day => start_day, :end_day => end_day ])
-
-
when "all"
-
#nothing to do here
-
when "range"
-
if !options[:from].blank? && !options[:to].blank?
-
activities = activities.where(['created_at BETWEEN :start_day AND :end_day',
-
:start_day => options[:from] , :end_day => options[:to] ])
-
elsif !options[:from].blank?
-
activities = activities.where(['created_at >= :start_day',
-
:start_day => options[:from] ])
-
elsif !options[:to].blank?
-
activities = activities.where(['created_at <= :end_day',
-
:end_day => options[:to] ])
-
else
-
# just like all nothing to do
-
end
-
-
end
-
activities
-
end
-
-
1
def self.migrate_site_activity collection_id
-
options = {
-
:id => collection_id,
-
:type => "all"
-
}
-
-
activities = search_collection(options) # search activities from criterias
-
activities = activities.select{|activity| !activity.site.nil?} # some sites were remove but there activity log still in db
-
migrate_activities(activities)
-
end
-
-
1
def self.migrate_activities activities
-
sites = {} # store unique sites from activities
-
activities.each do |activity|
-
sites[activity.site.id] = activity.site if activity.site
-
end
-
-
sites.each do |site_id, site|
-
site_activities = activities.select{|activity| (activity.site and activity.site.id == site.id) }
-
migrate_activities_of_site site_activities, site
-
end
-
end
-
-
1
def self.migrate_activities_of_site site_activities, site
-
1
last_properties = site.properties
-
1
last_lat = site.lat
-
1
last_lng = site.lng
-
1
last_name = site.name
-
-
1
site_activities.each do |activity|
-
5
if(activity.action == "changed")
-
5
activity.data["properties"] = last_properties.dup
-
5
activity.data["lat"] = last_lat
-
5
activity.data["lng"] = last_lng
-
5
activity.data["name"] = activity.data["name"] || last_name
-
5
activity.save
-
-
5
if(!activity.data["changes"]["lat"].nil? && !activity.data["changes"]["lat"].empty?)
-
1
last_lat = activity.data["changes"]["lat"][0]
-
end
-
-
5
if(!activity.data["changes"]["lng"].nil? && !activity.data["changes"]["lng"].empty?)
-
1
last_lng = activity.data["changes"]["lng"][0]
-
end
-
-
5
if(!activity.data["changes"]["properties"].nil? && !activity.data["changes"]["properties"].empty?)
-
3
activity.data["changes"]["properties"][0].each do |key, value|
-
6
last_properties[key] = value
-
end
-
end
-
end
-
end
-
1
site_activities
-
end
-
-
-
1
def self.to_csv_file options, filename
-
collection = Collection.find(options[:id])
-
CSV.open(filename, 'w') do |csv|
-
colunm_header = [
-
"User",
-
"Site",
-
"SiteCode",
-
"Lat",
-
"Lng",
-
"Date"
-
]
-
-
-
column_keys = {} #column properties of csv stored in "field"
-
field_kinds = {}
-
-
collection.fields.each do |field|
-
column_keys[field.id] = field.name
-
field_kinds[field.id.to_s] = field.kind
-
end
-
-
# add column properties to csv column header
-
column_keys.each do |key, value|
-
colunm_header << value
-
end
-
-
colunm_header << "Action"
-
csv << colunm_header
-
-
-
activities = search_collection(options) # search activities from criterias
-
sites = {} # store unique sites from activities
-
-
activities.each do |activity|
-
sites[activity.site.id] = activity.site if activity.site
-
end
-
-
sites.each do |site_id, site|
-
properties_row = {}
-
column_keys.each do |col_id, col_name|
-
properties_row[col_id.to_s] = ""
-
end
-
-
site_activities = activities.select{|activity| (activity.site and activity.site.id == site.id) }
-
-
site_activities.each do |activity|
-
properties_row = properties_row.merge(activity.data["properties"] || {} )
-
row = [
-
activity.user.email,
-
activity.data["name"] ,
-
activity.site.id_with_prefix ,
-
activity.data["lat"] ,
-
activity.data["lng"] ,
-
activity.updated_at
-
]
-
properties_row.each do |col_key, col_value|
-
if field_kinds[col_key] == 'photo' and not col_value.empty?
-
col_value = "#{Settings.protocol}://" + Settings.host + "/photo_field/" + col_value
-
end
-
row << col_value
-
end
-
-
row << activity.action
-
#row << activity.description
-
-
csv << row
-
end
-
-
#put 3 empty rows to separate each site
-
number_empty_row = 1
-
number_empty_row.times do
-
csv << Array.new(colunm_header.size){ "" }
-
end
-
end
-
end
-
end
-
-
1
def description
-
1746
case [item_type, action]
-
when ['collection', 'created']
-
503
I18n.t('views.activities.table.collection_was_created', name: data['name'])
-
when ['collection', 'deleted']
-
I18n.t('views.activities.table.collection_was_deleted', name: data['name'])
-
when 'collection_imported'
-
I18n.t('views.activities.table.import_wizard', sites_text: sites_were_imported_text)
-
when ['collection', 'csv_imported']
-
3
I18n.t('views.activities.table.import_csv', sites_text: sites_were_imported_text)
-
when ['layer', 'created']
-
561
fields_str = data['fields'].map { |f| "#{f['name']} (#{f['code']})" }.join ', '
-
476
str = I18n.t('views.activities.table.layer_was_created', name: data['name'], field: fields_str)
-
when ['layer', 'changed']
-
16
layer_changed_text
-
when ['layer', 'deleted']
-
5
str = I18n.t('views.activities.table.layer_was_deleted', name: data['name'])
-
when ['site', 'created']
-
635
I18n.t('views.activities.table.site_was_created', name: data['name'])
-
when ['site', 'changed']
-
61
site_changed_text
-
when ['site', 'deleted']
-
6
I18n.t('views.activities.table.site_was_deleted', name: data['name'])
-
end
-
end
-
-
1
def item_id
-
case item_type
-
when 'collection'
-
collection_id
-
when 'layer'
-
layer_id
-
when 'site'
-
site_id
-
end
-
end
-
-
1
private
-
-
1
def sites_were_imported_text
-
3
sites_created_text = "#{data['sites']} site#{data['sites'] == 1 ? '' : 's'}"
-
3
"#{sites_created_text} were imported"
-
end
-
-
1
def site_changed_text
-
61
only_name_changed, changes = site_changes_text
-
61
if only_name_changed
-
3
I18n.t('views.activities.table.site_was_renamed', name: data['name'], new_name: data['changes']['name'][1])
-
else
-
58
I18n.t('views.activities.table.site_was_changed', name: data['name'], changes: changes)
-
end
-
end
-
-
1
def site_changes_text
-
61
fields = collection.fields.index_by(&:es_code) if collection
-
61
if fields.length > 0
-
57
text_changes = []
-
57
only_name_changed = false
-
-
57
if (change = data['changes']['name'])
-
11
text_changes << I18n.t('views.activities.table.name_changed', from: change[0], to: change[1])
-
11
only_name_changed = true
-
end
-
-
57
if data['changes']['lat'] && data['changes']['lng']
-
12
text_changes << I18n.t('views.activities.table.location_changed', from: format_location(data['changes'], :from), to: format_location(data['changes'], :to))
-
12
only_name_changed = false
-
end
-
-
57
if data['changes']['properties']
-
33
properties = data['changes']['properties']
-
-
33
properties[0].each do |key, old_value|
-
48
new_value = properties[1][key]
-
48
if new_value != old_value
-
40
field = fields[key]
-
40
code = field.try(:code)
-
40
text_changes << I18n.t('views.activities.table.code_changed',code: code, from: format_value(field, old_value), to: format_value(field, new_value))
-
end
-
end
-
-
33
properties[1].each do |key, new_value|
-
68
if !properties[0].has_key? key
-
29
field = fields[key]
-
29
code = field.try(:code)
-
29
to_new_value = new_value.nil? ? I18n.t('views.activities.table.nothing') : format_value(field, new_value)
-
29
text_changes << I18n.t('views.activities.table.code_changed',code: code, from: I18n.t('views.activities.table.nothing'), to: to_new_value)
-
end
-
end
-
-
33
only_name_changed = false
-
end
-
-
57
[only_name_changed, text_changes.join(', ')]
-
end
-
end
-
-
1
def layer_changed_text
-
16
only_name_changed, changes = layer_changes_text
-
16
if only_name_changed
-
5
I18n.t('views.activities.table.layer_was_renamed', name: data['name'], new_name: data['changes']['name'][1])
-
else
-
11
I18n.t('views.activities.table.layer_changed', name: data['name'], changes: changes)
-
end
-
end
-
-
1
def layer_changes_text
-
16
text_changes = []
-
16
only_name_changed = false
-
-
16
if (change = data['changes']['name'])
-
5
text_changes << I18n.t('views.activities.table.name_changed', from: change[0], to: change[1])
-
5
only_name_changed = true
-
end
-
-
16
if data['changes']['added']
-
2
data['changes']['added'].each do |field|
-
2
text_changes << I18n.t('views.activities.table.field_was_added', kind: field['kind'], name: field['name'], code: field['code'])
-
end
-
2
only_name_changed = false
-
end
-
-
16
if data['changes']['changed']
-
6
data['changes']['changed'].each do |field|
-
6
['name', 'code', 'kind'].each do |key|
-
18
if field[key].is_a? Array
-
4
text_changes << I18n.t('views.activities.table.field_key_changed', kind: old_value(field['kind']), name: old_value(field['name']), code: old_value(field['code']), key: key, new_key: field[key][1])
-
end
-
end
-
-
6
if field['config'].is_a?(Array)
-
2
old_options = (field['config'][0] || {})['options']
-
2
new_options = (field['config'][1] || {})['options']
-
2
if old_options != new_options
-
2
text_changes << I18n.t('views.activities.table.field_option_changed', kind: old_value(field['kind']), name: old_value(field['name']), code: old_value(field['code']), old_options: format_options(old_options), new_options: format_options(new_options))
-
end
-
end
-
end
-
6
only_name_changed = false
-
end
-
-
16
if data['changes']['deleted']
-
3
data['changes']['deleted'].each do |field|
-
3
text_changes << I18n.t('views.activities.table.field_was_deleted', kind: field['kind'], name: field['name'], code: field['code'])
-
end
-
3
only_name_changed = false
-
end
-
-
16
[only_name_changed, text_changes.join(', ')]
-
end
-
-
1
def old_value(value)
-
18
value.is_a?(Array) ? value[0] : value
-
end
-
-
1
def format_value(field, value)
-
109
if field && field.yes_no?
-
3
value == 'true' || value == '1' ? 'yes' : 'no'
-
106
elsif field && field.select_one?
-
10
format_option field, value
-
96
elsif field && field.select_many? && value.is_a?(Array)
-
29
value.map { |v| format_option field, v }
-
else
-
85
value.is_a?(String) ? "#{value}" : value
-
end
-
end
-
-
1
def format_option(field, value)
-
69
option = field.config['options'].find { |o| o['id'] == value }
-
28
option ? "#{option['label']} (#{option['code']})" : value
-
end
-
-
1
def format_options(options)
-
8
(options || []).map { |option| "#{option['label']} (#{option['code']})" }
-
end
-
-
1
def format_location(changes, dir)
-
24
idx = dir == :from ? 0 : 1
-
24
lat = changes['lat'][idx]
-
24
lng = changes['lng'][idx]
-
24
if lat
-
20
result = "(#{((lat) * 1e6).round / 1e6.to_f}"
-
20
if lng
-
20
result = result+", #{((lng) * 1e6).round / 1e6.to_f})"
-
end
-
20
result
-
else
-
4
I18n.t('views.activities.table.nothing')
-
end
-
end
-
end
-
1
module Activity::AwareConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
# The user that creates/makes changes to this object
-
2
attr_accessor :user
-
-
# Set to true to stop creating Activities for this object
-
2
attr_accessor :mute_activities
-
-
2
validates_presence_of :user, :if => :new_record?, :unless => :mute_activities
-
end
-
end
-
1
class Clusterer
-
1
CellSize = 115.0
-
-
1
def initialize(zoom)
-
28
@zoom = zoom
-
28
@width, @height = self.class.cell_size_for zoom
-
50
@clusters = Hash.new { |h, k| h[k] = {lat_sum: 0, lng_sum: 0, alert: false, status: true, ord: 100, count: 0, min_lat: 90, max_lat: -90, min_lng: 180, max_lng: -180, highlighted: false } }
-
28
@sites = []
-
28
@clustering_enabled = @zoom < 20
-
28
@highlight = {}
-
end
-
-
1
def self.cell_size_for(zoom)
-
44
zoom = zoom.to_i
-
44
zoom = 2 ** (zoom)
-
44
[CellSize / zoom, CellSize / zoom]
-
end
-
-
1
def self.zoom_for(size)
-
Math.log2(CellSize / size).floor
-
end
-
-
1
def highlight(hierarchy_info)
-
20
@highlight[:hierarchy_code] = hierarchy_info[:code]
-
20
@highlight[:hierachies_selected] = hierarchy_info[:selected]
-
end
-
-
1
def add(site)
-
37
if @clustering_enabled
-
33
lat, lng = site[:lat].to_f, site[:lng].to_f
-
33
x, y = cell_for site
-
33
cluster = @clusters["#{x}:#{y}"]
-
33
cluster[:id] = "#{@zoom}:#{x}:#{y}"
-
33
cluster[:collection_id] ||= site[:collection_id]
-
33
cluster[:count] += 1
-
33
cluster[:min_lat] = lat if lat < cluster[:min_lat]
-
33
cluster[:min_lng] = lng if lng < cluster[:min_lng]
-
33
cluster[:max_lat] = lat if lat > cluster[:max_lat]
-
33
cluster[:max_lng] = lng if lng > cluster[:max_lng]
-
33
cluster[:status] = false if site[:collection_id] != cluster[:collection_id]
-
33
cluster[:icon] = site[:icon] ? site[:icon] : ''
-
33
cluster[:lat_sum] += lat
-
33
cluster[:lng_sum] += lng
-
33
cluster[:highlighted] ||= !site[:property].nil? && !@highlight[:hierachies_selected].nil? &&
-
7
(site[:property] & @highlight[:hierachies_selected]).present?
-
33
Plugin.hooks(:clusterer).each do |clusterer|
-
33
clusterer[:map].call site, cluster
-
end
-
-
33
if cluster[:count] == 1
-
22
cluster[:site] = site.dup
-
else
-
11
cluster.delete :site
-
end
-
else
-
4
@sites.push site.dup
-
end
-
end
-
-
1
def clusters
-
27
result = {}
-
27
if @clustering_enabled
-
26
clusters_to_return = []
-
26
sites_to_return = []
-
-
26
@clusters.each_value do |cluster|
-
22
count = cluster[:count]
-
22
if count == 1
-
11
site = cluster[:site]
-
11
site[:highlighted] = !site[:property].nil? && !@highlight[:hierachies_selected].nil? &&
-
2
(site[:property] & @highlight[:hierachies_selected]).present?
-
11
site.delete(:property)
-
-
11
sites_to_return.push site
-
else
-
11
hash = {
-
id: cluster[:id],
-
lat: cluster[:lat_sum] / count,
-
lng: cluster[:lng_sum] / count,
-
min_lat: cluster[:min_lat],
-
min_lng: cluster[:min_lng],
-
max_lat: cluster[:max_lat],
-
max_lng: cluster[:max_lng],
-
icon: cluster[:status] ? cluster[:icon] : 'default',
-
count: count,
-
status: cluster[:status],
-
highlighted: cluster[:highlighted]
-
}
-
-
11
Plugin.hooks(:clusterer).each do |clusterer|
-
11
clusterer[:reduce].call cluster, hash
-
end
-
-
11
hash[:site_ids] = cluster[:site_ids] if cluster[:site_ids]
-
11
clusters_to_return.push hash
-
end
-
end
-
-
26
result[:clusters] = clusters_to_return if clusters_to_return.present?
-
26
result[:sites] = sites_to_return if sites_to_return.present?
-
else
-
# Disambiguation for sites in identical location
-
1
result[:sites] = []
-
1
result[:original_ghost] = []
-
1
r = 15
-
5
sites_by_lat_lng = @sites.group_by {|s| [s[:lat], s[:lng]] }
-
1
sites_by_lat_lng.each do |k, sites|
-
1
quantity = sites.count
-
1
if quantity == 1
-
result[:sites].push sites.first
-
else
-
1
result[:original_ghost].push(lat: k.first, lng: k.last)
-
1
angle_each = 2 * Math::PI / quantity
-
1
sites.each_with_index do |site, index|
-
4
angle = angle_each * index
-
4
site[:ghost_radius] = angle
-
4
result[:sites].push site
-
end
-
end
-
end
-
end
-
-
27
result
-
end
-
-
1
def set_clustering_enabled status
-
@clustering_enabled = status
-
end
-
-
1
protected
-
-
1
def cell_for(site)
-
33
x = ((90 + site[:lng]) / @width).floor
-
33
y = ((180 + site[:lat]) / @height).floor
-
33
[x, y]
-
end
-
end
-
1
class Collection < ActiveRecord::Base
-
1
include Collection::CsvConcern
-
1
include Collection::ShpConcern
-
1
include Collection::GeomConcern
-
1
include Collection::KmlConcern
-
1
include Collection::ElasticsearchConcern
-
1
include Collection::PluginsConcern
-
1
include Collection::ImportLayersSchemaConcern
-
-
-
1
validates_presence_of :name
-
-
1
has_many :memberships, :dependent => :destroy
-
1
has_many :layer_memberships, dependent: :destroy
-
1
has_many :users, through: :memberships
-
1
has_many :sites, dependent: :delete_all
-
887
has_many :layers, -> { order('ord')}, dependent: :destroy
-
3555
has_many :fields, -> { order('ord')}
-
1
has_many :thresholds, dependent: :destroy
-
1
has_many :reminders, dependent: :destroy
-
1
has_many :share_channels, dependent: :destroy
-
1
has_many :channels, :through => :share_channels
-
1
has_many :activities
-
1
has_many :snapshots, dependent: :destroy
-
1
has_many :user_snapshots, :through => :snapshots
-
1
has_many :site_histories, dependent: :destroy
-
1
has_many :layer_histories, dependent: :destroy
-
1
has_many :field_histories, dependent: :destroy
-
1
has_many :messages, dependent: :destroy
-
-
1
has_many :share_national_channels
-
1
has_many :channels, through: :share_national_channels
-
-
1
OPERATOR = {">" => "gt", "<" => "lt", ">=" => "gte", "<=" => "lte", "=>" => "gte", "=<" => "lte", "=" => "eq"}
-
-
1
attr_accessor :time_zone
-
-
1
after_save :touch_lifespan
-
1
after_destroy :touch_lifespan
-
-
1
def max_value_of_property(es_code)
-
1
client = Elasticsearch::Client.new
-
1
results = client.search index: index_name, type: 'site', body: {
-
sort: {es_code => 'desc'},
-
size: 2000,
-
}
-
results["hits"]["hits"].first['_source']['properties'][es_code] rescue 0
-
end
-
-
1
def snapshot_for(user)
-
2
user_snapshots.where(user_id: user.id).first.try(:snapshot)
-
end
-
-
1
def is_site_exist? device_id, external_id
-
9
flag = nil
-
9
result = nil
-
9
if device_id
-
8
flag = false
-
8
sites.each do |site|
-
12
if site.device_id == device_id
-
8
if site.external_id.to_s == external_id.to_s
-
#update
-
2
result = site
-
2
flag = true
-
2
break
-
else
-
#create
-
6
flag = false
-
end
-
else
-
#create
-
4
flag = false
-
end
-
end
-
end
-
9
return result
-
end
-
-
1
def writable_fields_for(user)
-
1
membership = user.membership_in self
-
1
return [] unless membership
-
-
1
target_fields = fields.includes(:layer)
-
-
1
if membership.admin?
-
target_fields = target_fields.all
-
else
-
1
lms = LayerMembership.where(user_id: user.id, collection_id: self.id).inject({}) do |hash, lm|
-
1
hash[lm.layer_id] = lm
-
1
hash
-
end
-
-
4
target_fields = target_fields.select {|f| lms[f.layer_id] && lms[f.layer_id].write}
-
-
end
-
1
target_fields
-
end
-
-
1
def site_ids_write_permission(user)
-
site_ids, membership = [], user.membership_in(self)
-
if membership
-
write_sites_permission = membership.write_sites_permission
-
site_ids.concat(write_sites_permission['some_sites'].map{ |site| site['id'].to_i}) if write_sites_permission
-
end
-
-
site_ids.uniq
-
end
-
-
1
def site_ids_read_permission(user)
-
site_ids, membership = [], user.membership_in(self)
-
if membership
-
read_sites_permission = membership.read_sites_permission
-
site_ids.concat(read_sites_permission['some_sites'].map{ |site| site['id'].to_i}) if read_sites_permission
-
end
-
-
site_ids.uniq
-
end
-
-
1
def site_ids_permission(user)
-
20
site_ids, membership = [], user.membership_in(self)
-
20
if membership
-
19
read_sites_permission = membership.read_sites_permission
-
19
write_sites_permission = membership.write_sites_permission
-
-
19
site_ids.concat(read_sites_permission['some_sites'].map{ |site| site['id'].to_i}) if read_sites_permission
-
19
site_ids.concat(write_sites_permission['some_sites'].map{ |site| site['id'].to_i}) if write_sites_permission
-
end
-
-
20
site_ids.uniq
-
end
-
-
-
1
def visible_fields_for(user, options, language = nil)
-
40
if user.try(:is_guest)
-
return fields.includes(:layer).all
-
end
-
-
40
membership = user.try :membership_in, self
-
40
return [] unless membership
-
39
if options[:snapshot_id]
-
2
date = Snapshot.where(id: options[:snapshot_id]).first.date
-
2
target_fields = field_histories.at_date(date).includes(:layer)
-
else
-
37
target_fields = fields.includes(:layer)
-
end
-
39
if membership.admin?
-
38
target_fields = target_fields.to_a
-
else
-
1
lms = LayerMembership.where(user_id: user.id, collection_id: self.id).inject({}) do |hash, lm|
-
1
hash[lm.layer_id] = lm
-
1
hash
-
end
-
3
target_fields = target_fields.select { |f| lms[f.layer_id] && lms[f.layer_id].read }
-
end
-
268
target_fields.sort! { |x, y| x[:ord] <=> y[:ord] }
-
end
-
-
1
def visible_layers_for(user, options = {}, language = nil)
-
3
target_fields = visible_fields_for(user, options, language)
-
3
layers = target_fields.map(&:layer).uniq.map do |layer|
-
{
-
id: layer.id,
-
name: layer.name,
-
ord: layer.ord,
-
3
}
-
end
-
3
membership = user.membership_in self
-
3
if !user.is_guest && !membership.try(:admin?)
-
2
lms = LayerMembership.where(user_id: user.id, collection_id: self.id).to_a.inject({}) do |hash, lm|
-
1
hash[lm.layer_id] = lm
-
1
hash
-
end
-
end
-
-
3
layers.each do |layer|
-
8
layer[:fields] = target_fields.select { |field| field.layer_id == layer[:id] }
-
3
layer[:fields].map! do |field|
-
{
-
id: field.es_code,
-
name: field.name,
-
code: field.code,
-
kind: field.kind,
-
config: field.config,
-
ord: field.ord,
-
is_mandatory: field.is_mandatory,
-
is_enable_field_logic: field.is_enable_field_logic,
-
# field_logic_value: field.field_logic_value,
-
writeable: user.is_guest ? false : !lms || lms[field.layer_id].write
-
3
}
-
end
-
end
-
4
layers.sort! { |x, y| x[:ord] <=> y[:ord] }
-
-
3
layers
-
end
-
-
# Returns the next ord value for a layer that is going to be created
-
1
def next_layer_ord
-
483
layer = layers.select('max(ord) as o').first
-
483
layer ? layer['o'].to_i + 1 : 1
-
end
-
-
1
def update_activities
-
ActiveRecord::Base.transaction do
-
Activity.where(collection_id: id).update_all(:collection_id => nil)
-
end
-
end
-
-
1
def delete_sites_and_activities
-
ActiveRecord::Base.transaction do
-
Site.where(collection_id: id).delete_all
-
recreate_index
-
end
-
end
-
-
1
def thresholds_test(site)
-
1414
catch(:threshold) {
-
1414
thresholds.order(:ord).each do |threshold|
-
11
threshold.test site.properties if threshold.is_all_site || threshold.sites.any? { |selected| selected["id"] == site.id }
-
end
-
1411
nil
-
}
-
end
-
-
1
def query_sites(option)
-
6
operator = operator_parser option[:operator]
-
6
field = Field.find_by_code option[:code]
-
-
6
search = self.new_search
-
6
search.use_codes_instead_of_es_codes
-
-
6
search.send operator, field, option[:value]
-
6
results = search.results
-
6
response_prepare(option[:code], field.id, results)
-
end
-
-
1
def response_prepare(field_code, field_id, results)
-
6
array_result = []
-
6
results.each do |r|
-
array_result.push "#{r["_source"]["name"]}=#{r["_source"]["properties"][field_id.to_s]}"
-
end
-
6
response_sms = (array_result.empty?)? "There is no site matched" : array_result.join(", ")
-
6
result = "[\"#{field_code}\"] in #{response_sms}"
-
6
result
-
end
-
-
1
def operator_parser(op)
-
12
OPERATOR[op]
-
end
-
-
1
def active_gateway
-
self.channels.each do |channel|
-
return channel if channel.client_connected && channel.is_enable && !channel.share_channels.find_by_collection_id(id).nil?
-
end
-
nil
-
end
-
-
1
def get_user_owner
-
2
memberships.find_by_admin(true).user
-
end
-
-
1
def get_gateway_under_user_owner
-
1
get_user_owner.get_gateway
-
end
-
-
1
def register_gateways_under_user_owner(owner_user)
-
393
self.channels = owner_user.channels.where(is_enable: true)
-
end
-
-
# Returns a dictionary of :code => :es_code of all the fields in the collection
-
1
def es_codes_by_field_code
-
1
self.fields.inject({}) do |dict, field|
-
4
dict[field.code] = field.es_code
-
4
dict
-
end
-
end
-
-
1
def self.filter_sites params
-
4
builder = Collection.find(params[:collection_id]).sites
-
4
if !params[:from].blank? && !params[:to].blank?
-
from = params[:from]
-
to = params[:to]
-
builder = builder.where(['sites.created_at BETWEEN :from AND :to', :from => from, :to => to])
-
elsif !params[:from].blank?
-
from = params[:from]
-
builder = builder.where(['sites.created_at >= :from', :from => from])
-
elsif !params[:to].blank?
-
to = params[:to]
-
builder = builder.where(['sites.created_at <= :to', :to => to])
-
end
-
4
builder
-
end
-
-
1
def self.filter_page limit, offset, builder
-
2
builder = builder.limit limit if limit
-
2
builder = builder.offset offset if offset
-
2
builder.order("sites.created_at DESC")
-
end
-
-
1
def self.filter_page_order_by_name limit, offset, builder
-
2
builder = builder.limit limit if limit
-
2
builder = builder.offset offset if offset
-
2
builder.order("sites.name ASC")
-
end
-
-
1
def new_site_properties
-
2
self.fields.each_with_object({}) do |field, hash|
-
value = field.default_value_for_create(self)
-
hash[field.es_code] = value if value
-
end
-
end
-
-
1
def get_number_of_admin_membership
-
self.memberships.where(:admin => true).count
-
end
-
-
1
def self.public_collections
-
2
Collection.where(:public => true)
-
end
-
-
1
def self.recreate_site_index collection_id
-
Collection.find(collection_id).recreate_index
-
end
-
-
1
def create_deleted_activity(user)
-
Activity.create! item_type: 'collection', action: 'deleted', collection_id: nil, collection_name: name, layer_id: nil, user_id: user.id, 'data' => {'name' => name}
-
end
-
-
1
def layers_to_json(at_present, user)
-
if at_present
-
layers.includes(:fields).as_json(include: :fields)
-
else
-
current_user_snapshot = UserSnapshot.for(user, self)
-
layer_histories.at_date(current_user_snapshot.snapshot.date)
-
.includes(:field_histories)
-
.as_json(include: :field_histories)
-
end
-
end
-
-
1
private
-
-
1
def touch_lifespan
-
1492
Telemetry::Lifespan.touch_collection self
-
end
-
-
end
-
1
module Collection::CsvConcern
-
1
extend ActiveSupport::Concern
-
# include Rails.application.routes.url_helpers
-
1
def csv_template
-
CSV.generate do |csv|
-
csv << csv_header
-
csv << [1, "Site 1", 1.234, 5.678]
-
csv << [2, "Site 2", 3.456, 4.567]
-
end
-
end
-
-
1
def to_csv(elastic_search_api_results, user, snapshot_id = nil, options = {})
-
10
fields = self.visible_fields_for(user, {snapshot_id: snapshot_id})
-
10
fields.each(&:cache_for_read)
-
-
10
CSV.generate do |csv|
-
10
header = ['resmap-id', 'name', 'lat', 'long']
-
10
fields.each do |field|
-
74
field.csv_headers.each do |column_header|
-
74
header << column_header
-
end
-
end
-
10
header << 'last updated'
-
10
csv << header
-
-
10
elastic_search_api_results.each do |result|
-
6
source = result['_source']
-
-
6
row = [source['id'], source['name'], source['location'].try(:[], 'lat'), source['location'].try(:[], 'lon')]
-
6
fields.each do |field|
-
38
field.csv_values(source['properties'][field.code], options[:human]).each do | value |
-
38
if field.kind == 'yes_no'
-
4
row << (Field.yes?(source['properties'][field.code]) ? 'yes' : 'no')
-
elsif field.kind == 'photo'
-
row << "#{Settings.host}/photo_field/#{source['properties'][field.code]}"
-
else
-
34
row << Array(source['properties'][field.code]).join(", ")
-
end
-
end
-
end
-
6
row << Site.iso_string_to_rfc822(source['updated_at'])
-
6
csv << row
-
end
-
end
-
end
-
-
1
def location_csv(locations)
-
CSV.generate do |csv|
-
locations.each do |location|
-
csv << [location["code"], location["name"], location["latitude"], location["longitude"]]
-
end
-
end
-
end
-
-
1
def sample_csv(user = nil)
-
1
fields = self.fields
-
-
1
CSV.generate do |csv|
-
1
header = ['name', 'lat', 'long']
-
1
writable_fields = writable_fields_for(user)
-
2
writable_fields.each { |field| header << field.code }
-
1
csv << header
-
1
row = ['Paris', 48.86, 2.35]
-
1
writable_fields.each do |field|
-
1
row << Array(field.sample_value user).join(", ")
-
end
-
1
csv << row
-
end
-
end
-
-
1
def import_csv(user, string_or_io)
-
2
Collection.transaction do
-
2
csv = CSV.new string_or_io, return_headers: false
-
-
2
new_sites = []
-
2
csv.each do |row|
-
5
next unless row[0].present? && row[0] != 'resmap-id'
-
-
3
site = sites.new name: row[1].strip
-
3
site.mute_activities = true
-
3
site.lat = row[2].strip if row[2].present?
-
3
site.lng = row[3].strip if row[3].present?
-
3
new_sites << site
-
end
-
-
2
new_sites.each &:save!
-
-
2
Activity.create! item_type: 'collection', action: 'csv_imported', collection_id: id, user_id: user.id, 'data' => {'sites' => new_sites.length}
-
end
-
end
-
-
1
def decode_hierarchy_csv(string)
-
-
12
csv = CSV.parse(string)
-
-
# First read all items into a hash
-
# And validate it's content
-
11
items = validate_format(csv)
-
-
# Add to parents
-
11
items.each do |order, item|
-
47
if item[:parent].present? && !item[:error].present?
-
105
parent_candidates = items.select{|key, hash| hash[:id] == item[:parent]}
-
-
15
if parent_candidates.any?
-
15
parent = parent_candidates.first[1]
-
end
-
-
15
if parent
-
15
parent[:sub] ||= []
-
15
parent[:sub] << item
-
end
-
end
-
end
-
-
# Remove those that have parents, and at the same time delete their parent key
-
11
items = items.reject do |order, item|
-
47
if item[:parent] && !item[:error].present?
-
15
item.delete :parent
-
15
true
-
else
-
32
false
-
end
-
end
-
-
-
11
items.values
-
-
rescue Exception => ex
-
1
return [{error: ex.message}]
-
-
end
-
-
1
def decode_location_csv(string)
-
csv = CSV.parse(string)
-
-
items = validate_format_location(csv)
-
-
locations = []
-
items.each do |item|
-
locations.push item[1]
-
end
-
-
locations
-
-
rescue Exception => ex
-
return [{error: ex.message}]
-
end
-
-
1
def validate_format_location(csv)
-
i = 0
-
items = {}
-
csv.each do |row|
-
item = {}
-
if row[0] == 'Code'
-
next
-
else
-
i = i+1
-
item[:order] = i
-
-
if row.length != 4
-
item[:error] = "Wrong format."
-
item[:error_description] = "Invalid column number"
-
else
-
-
#Check unique name
-
name = row[1].strip
-
# if items.any?{|item| item.second[:name] == name}
-
# item[:error] = "Invalid name."
-
# item[:error_description] = "location name should be unique"
-
# error = true
-
# end
-
-
#Check unique id
-
code = row[0].strip
-
# if items.any?{|item| item.second[:code] == code}
-
# item[:error] = "Invalid code."
-
# item[:error_description] = "location code should be unique"
-
# error = true
-
# end
-
-
# if !error
-
item[:code] = code
-
item[:name] = name
-
item[:latitude] = row[2].strip
-
item[:longitude] = row[3].strip
-
# end
-
end
-
-
items[item[:order]] = item
-
end
-
end
-
items
-
end
-
-
1
def validate_format(csv)
-
11
i = 0
-
11
items = {}
-
11
csv.each do |row|
-
50
item = {}
-
50
if row[0] == 'ID'
-
3
next
-
else
-
47
i = i+1
-
47
item[:order] = i
-
-
47
if row.length != 3
-
4
item[:error] = "Wrong format."
-
4
item[:error_description] = "Invalid column number"
-
else
-
-
#Check unique name
-
43
name = row[2].strip
-
124
if items.any?{|item| item.second[:name] == name}
-
3
item[:error] = "Invalid name."
-
3
item[:error_description] = "Hierarchy name should be unique"
-
3
error = true
-
end
-
-
#Check unique id
-
43
id = row[0].strip
-
124
if items.any?{|item| item.second[:id] == id}
-
2
item[:error] = "Invalid id."
-
2
item[:error_description] = "Hierarchy id should be unique"
-
2
error = true
-
end
-
-
#Check parent id exists
-
43
parent_id = row[1]
-
71
if(parent_id.present? && !csv.any?{|csv_row| csv_row[0].strip == parent_id.strip})
-
1
item[:error] = "Invalid parent value."
-
1
item[:error_description] = "ParentID should match one of the Hierarchy ids"
-
1
error = true
-
end
-
-
43
if !error
-
37
item[:id] = id
-
37
item[:parent] = row[1].strip if row[1].present?
-
37
item[:name] = name
-
end
-
end
-
-
47
items[item[:order]] = item
-
end
-
end
-
11
items
-
end
-
-
1
private
-
-
1
def csv_header
-
["Site ID", "Name", "Lat", "Lng"]
-
end
-
end
-
1
module Collection::ElasticsearchConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_create :create_index
-
1
after_destroy :destroy_index
-
end
-
-
1
def create_index
-
682
index_properties = {
-
refresh: true,
-
mappings: { site: site_mapping }
-
}
-
682
index_properties.merge!(Site::IndexUtils::DefaultIndexSettings)
-
-
682
result = Elasticsearch::Client.new.indices.create index: index_name, body: index_properties
-
-
682
unless result["acknowledged"]
-
error = "Can't create index for collection #{name} (ID: #{id})."
-
Rails.logger.error error
-
Rails.logger.error "ElasticSearch response was: #{result}."
-
raise error
-
end
-
-
# This is because in the tests collections are created and the
-
# fields association will almost always be empty, but it needs to
-
# be refreshed afte creating layers and fields.
-
682
clear_association_cache if Rails.env.test?
-
end
-
-
1
def site_mapping
-
2641
Site::IndexUtils.site_mapping(fields)
-
end
-
-
1
def update_mapping
-
1959
client = Elasticsearch::Client.new
-
1959
client.indices.put_mapping index: index_name, type: 'site', body: {site: site_mapping}
-
1959
client.indices.refresh index: index_name
-
end
-
-
1
def recreate_index
-
destroy_index rescue nil
-
create_index
-
client = Elasticsearch::Client.new
-
docs = sites.map do |site|
-
site.collection = self
-
site.to_elastic_search
-
end
-
docs.each_slice(1000) do |docs_slice|
-
ops = []
-
docs_slice.each do |doc|
-
ops.push index: { _index: index_name, _type: 'site', _id: doc[:id]}
-
ops.push doc
-
end
-
client.bulk body: ops
-
end
-
client.indices.refresh index: index_name
-
end
-
-
1
def destroy_index
-
4
Elasticsearch::Client.new.indices.delete index: index_name
-
end
-
-
1
def index_name(options = {})
-
5376
self.class.index_name id, options
-
end
-
-
1
def new_search(options = {})
-
119
Search.new(self, options)
-
end
-
-
1
def elasticsearch_count
-
4
client = Elasticsearch::Client.new
-
4
if block_given?
-
2
value = client.count index: index_name, body: yield
-
else
-
2
value = client.count index: index_name
-
end
-
4
value["count"]
-
end
-
-
1
def new_map_search
-
MapSearch.new id
-
end
-
-
1
def index_names_with_options(options = {})
-
119
self.class.index_names_with_options(id, options)
-
end
-
-
1
module ClassMethods
-
1
INDEX_NAME_PREFIX = Rails.env == 'test' ? "collection_test" : "collection"
-
-
1
def index_name(id, options = {})
-
5514
if options[:snapshot_id]
-
62
return "#{INDEX_NAME_PREFIX}_#{id}_#{options[:snapshot_id]}"
-
end
-
-
5452
if options[:user]
-
snapshot = Collection.find(id).snapshot_for(options[:user])
-
if snapshot
-
return "#{INDEX_NAME_PREFIX}_#{id}_#{snapshot.id}"
-
end
-
end
-
-
5452
"#{INDEX_NAME_PREFIX}_#{id}"
-
end
-
-
1
def index_names_with_options(*ids, options)
-
# If we want the indices for many collections for a given user, it's faster
-
# to get all snapshots ids first instead of fetching them one by one for each collection.
-
# This optimization does that.
-
135
if options[:user] && !options[:snapshot_id]
-
collection_ids_to_snapshot_id = Snapshot.ids_for_collections_ids_and_user(ids, options[:user])
-
options.delete :user
-
end
-
-
135
index_names = ids.map do |id|
-
135
if collection_ids_to_snapshot_id
-
options[:snapshot_id] = collection_ids_to_snapshot_id[id.to_i]
-
end
-
-
135
index_name(id, options)
-
end
-
135
index_names.join ","
-
end
-
end
-
end
-
1
module Collection::GeomConcern
-
1
extend ActiveSupport::Concern
-
-
# Inovke this method to compute this collection's geometry in memory,
-
# just before saving it.
-
#
-
# (Putting as a before_create callback doesn't seem to work, the sites are empty)
-
1
def compute_geometry_in_memory
-
55
sites_with_location = sites.select{|x| x.lat && x.lng}
-
18
min_lat, max_lat, min_lng, max_lng = 90, -90, 180, -180
-
18
sites_with_location.each do |site|
-
16
min_lat = site.lat if site.lat < min_lat
-
16
max_lat = site.lat if site.lat > max_lat
-
16
min_lng = site.lng if site.lng < min_lng
-
16
max_lng = site.lng if site.lng > max_lng
-
end
-
18
set_bounding_box min_lat, max_lat, min_lng, max_lng
-
end
-
-
1
def compute_bounding_box
-
620
sites.where('lat is not null && lng is not null').select('min(lat) as v1, max(lat) as v2, min(lng) as v3, max(lng) as v4').each do |v|
-
620
set_bounding_box v.v1, v.v2, v.v3, v.v4 if v.v1 && v.v2 && v.v3 && v.v4
-
end
-
end
-
-
1
def set_bounding_box(min_lat, max_lat, min_lng, max_lng)
-
633
self.min_lat = min_lat
-
633
self.max_lat = max_lat
-
633
self.min_lng = min_lng
-
633
self.max_lng = max_lng
-
633
self.lat = (min_lat + max_lat) / 2
-
633
self.lng = (min_lng + max_lng) / 2
-
end
-
-
1
def compute_bounding_box!
-
620
compute_bounding_box
-
620
save!
-
end
-
end
-
1
module Collection::ImportLayersSchemaConcern
-
-
1
def import_schema(layers_string, user)
-
3
layers_json = JSON.parse layers_string
-
3
layers_json.each do |layer_json|
-
3
params = layer_json.except(*["created_at", "updated_at", "fields"])
-
3
layer = layers.new params
-
3
layer.user = user
-
3
if layer_json["fields"]
-
2
layer_json["fields"].each do |field_json|
-
2
field_params = field_json.except(*["created_at", "updated_at", "collection_id"])
-
2
field = layer.fields.new field_params
-
2
field.collection_id = self.id
-
end
-
end
-
3
layer.save!
-
end
-
end
-
end
-
1
require 'nokogiri'
-
1
module Collection::KmlConcern
-
1
extend ActiveSupport::Concern
-
-
1
def to_kml results
-
fields = {}
-
field_options = {}
-
field_kinds = {}
-
self.fields.each do |f|
-
fields["#{f["code"]}"] = f["name"]
-
if ['select_one','select_many'].include? f.kind
-
field_options["#{f["code"]}"] = {}
-
f["config"]["options"].each do |option|
-
field_options["#{f["code"]}"]["#{option['id'].to_s}"] = option['label']
-
end
-
end
-
field_kinds["#{f["code"]}"] = f["kind"]
-
end
-
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
-
xml.kml(:xmlns => "#{Settings.protocol}://earth.google.com/kml/2.1"){
-
xml.Document {
-
xml.name self.name
-
xml.open "1"
-
-
xml.Style(:id => "defaultstyle") do
-
-
xml.IconStyle {
-
xml.Icon {
-
xml.href "#{Settings.protocol}://maps.google.com/mapfiles/kml/pushpin/red-pushpin.png"
-
}
-
xml.scale '1.4'
-
}
-
-
xml.LabelStyle{
-
xml.color 'a1ff00ff'
-
xml.scale '1.4'
-
}
-
-
end
-
-
results.each do |r|
-
row = r["_source"]
-
xml.Placemark {
-
xml.name row["name"]
-
xml.styleUrl "#defaultstyle"
-
xml.LookAt {
-
if row["location"]
-
xml.longitude row["location"]["lon"]
-
xml.latitude row["location"]["lat"]
-
end
-
xml.altitude 0
-
xml.range 32185
-
xml.tilt 0
-
xml.heading 0
-
}
-
-
xml.ExtendedData {
-
row["properties"].each do |key, value|
-
xml.Data(:name => "#{fields[key]} (#{key})") {
-
case(field_kinds[key])
-
when "select_one"
-
xml.value field_options["#{key}"]["#{value}"]
-
when "select_many"
-
val_text = []
-
value.each do |v|
-
val_text.push field_options["#{key}"]["#{v}"]
-
end
-
xml.value val_text.join(", ")
-
when 'yes_no'
-
xml.value value == true ? 'Yes': 'No'
-
when 'photo'
-
xml.value "<image src='#{Settings.protocol}://#{Settings.host}/photo_field/#{value}' style='width:200px;' alt='#{value}' />"
-
else
-
xml.value value
-
end
-
}
-
end
-
xml.Data(:name => "Location") {
-
xml.value row["location"]
-
}
-
}
-
if(row["location"])
-
xml.Point {
-
xml.coordinates "#{row["location"]["lon"]},#{row["location"]["lat"]},0"
-
}
-
end
-
}
-
end
-
}
-
}
-
end
-
builder.to_xml
-
end
-
-
end
-
1
module Collection::PluginsConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
#serialize :plugins, Hash
-
end
-
-
1
def selected_plugins=(plugin_names)
-
# self.plugins = {}
-
# plugin_names.each do |name|
-
# next unless name.present?
-
# plugins[name] = {}
-
# end
-
end
-
-
1
def plugin_enabled?(key)
-
697
Settings.is_on? key
-
#plugins.has_key? key
-
end
-
-
1
def selected_plugins
-
Settings.selected_plugins
-
#plugins.keys
-
end
-
-
1
def each_plugin(&block)
-
Plugin.find_by_names(*selected_plugins).
-
each &block
-
end
-
-
# FIXME: not being used
-
1
def call_hooks name, *args
-
each_plugin do |plugin|
-
plugin.call_hook name, *args
-
end
-
end
-
-
1
def method_missing(method_name, *args, &block)
-
698
(method_name =~ /(\w+)_plugin_enabled?/).try(:zero?)? self.plugin_enabled?($1) : super
-
end
-
end
-
1
module Collection::ShpConcern
-
1
extend ActiveSupport::Concern
-
-
1
def to_shp(elastic_search_api_results = new_search.unlimited.api_results)
-
2
Dir.mktmpdir { |dir|
-
2
generate_shp File.join(dir, "#{self.id}.shp"), elastic_search_api_results
-
# compress_files dir
-
}
-
end
-
-
1
def generate_shp path, search_results
-
2
fields = self.class.resmap_dbf_fields | dbf_fields.values
-
# shp = ShpFile.create path, ShpType::POINT, field
-
# shp.transaction do |tr|
-
# search_results.each do |result|
-
# tr.add dbf_record_for result['_source']
-
# end
-
# end
-
# shp.close
-
end
-
-
1
def dbf_fields
-
@dbf_fields ||= Hash[
-
fields.map { |field|
-
2
[field, field.to_dbf_field]
-
}
-
2
]
-
end
-
-
1
def compress_files dir
-
path = File.join dir, "#{self.id}.zip"
-
Zip::ZipOutputStream.open(path) do |zos|
-
%w(shp shx dbf).each do |format|
-
filename = "#{self.id}.#{format}"
-
-
zos.put_next_entry filename
-
zos.print File.read File.join(dir, filename)
-
end
-
zos.put_next_entry "#{self.id}.prj"
-
zos.print Epsg.wgs84
-
end
-
IO.read path
-
end
-
-
1
def dbf_record_for source = {}
-
2
point = Point.from_x_y source['location'].try(:[], 'lon'), source['location'].try(:[], 'lat')
-
data = [
-
['resmap-id', source['id']],
-
['name', source['name']],
-
['created_at', Site.iso_string_to_rfc822(source['created_at'], time_zone)],
-
['updated_at', Site.iso_string_to_rfc822(source['updated_at'], time_zone)] ]
-
-
data |= dbf_fields.map { |field, _| [field.code, source['properties'][field.code]] }
-
-
ShpRecord.new point, Hash[ data ]
-
end
-
-
1
module ClassMethods
-
1
def resmap_dbf_fields
-
# fields = [
-
# dbf_field_for('resmap-id', type: 'N', length: 4, decimal: 0),
-
# dbf_field_for('name', type: 'C', length: 50),
-
# dbf_field_for('created_at', type: 'C', length: 40),
-
# dbf_field_for('updated_at', type: 'C', length: 40) ]
-
end
-
-
1
def dbf_field_for name, attrs = {}
-
5
Dbf::Field.new name, attrs[:type], attrs[:length], (attrs[:decimal] || 0)
-
end
-
end
-
end
-
1
module ElasticSearch::QueryHelper
-
1
class << self
-
# Returns a full text search query over the given collection, additionaly
-
# specifying which fields to use (will use the collection's fields if not specified).
-
#
-
# For example, if there's a select one field with code "foo" which has an option
-
# with code "bar" and label "baz", when searching for "baz" the generated query
-
# will be:
-
#
-
# foo:"bar" OR baz*
-
#
-
# because baz is the label of an option we want to look for, and also the text
-
# baz might appear somewhere else.
-
#
-
# If no field label would have matched, baz* would be the returned string.
-
#
-
# Addionally, range queries (as "greater than") are appended to the given 'es_search' parameter.
-
#
-
# Can return nil if no condition was generated except comparison of field values.
-
1
def full_text_search(text, es_search, collection, fields = nil)
-
26
search_hash = SearchParser.new text
-
-
26
conditions = []
-
-
26
if text = search_hash.search
-
21
ids = search_value_ids search_hash.search, collection, fields
-
-
21
if ids.present?
-
12
ids = ids.map { |k, v| %Q(#{k}:"#{v}") }
-
6
ids.push append_star(search_hash.search)
-
6
conditions.push "(#{ids.join " OR "})"
-
else
-
15
conditions.push append_star(search_hash.search)
-
end
-
end
-
-
26
search_hash.each do |key, value|
-
# Check that the field exists indeed in the collection,
-
# but only when not searching for name and id
-
5
if key.downcase == 'id' || key.downcase == 'name'
-
op = '='
-
else
-
14
field = collection.fields.find { |x| x.code == key || x.name == key}
-
5
next unless field
-
-
5
key = field.es_code
-
5
op, value = SearchParser.get_op_and_val value
-
-
# Check if the user is searching a label instead of the code
-
5
id = search_value_id field, /#{value}/i
-
5
value = id if id
-
end
-
-
5
case op
-
when '='
-
3
es_search.add_filter :term => {key => value}
-
when '<'
-
es_search.add_filter :range => {key => {lt: value}}
-
when '<='
-
es_search.add_filter :range => {key => {lte: value}}
-
when '>'
-
1
es_search.add_filter :range => {key => {gt: value}}
-
when '>='
-
1
es_search.add_filter :range => { key => {gte: value}}
-
end
-
end
-
-
26
conditions.length > 0 ? (conditions.join " AND ") : nil
-
end
-
-
1
private
-
-
# Searches value ids from their labels on this collections' fields,
-
# or in the given fields.
-
# Returns a hash of matching field codes and the ids. For example:
-
# {:field_es_code => :option_id}
-
1
def search_value_ids(text, collection, fields_to_search = nil)
-
21
fields_to_search ||= collection.fields
-
21
fields_to_search = fields_to_search.select &:select_kind?
-
-
21
codes = {}
-
21
search_text = Regexp.quote(text)
-
21
regex = /#{search_text}/i
-
21
fields_to_search.each do |field|
-
13
option_id = search_value_id field, regex
-
13
codes[field.es_code] = option_id if option_id
-
end
-
21
codes
-
end
-
-
1
def search_value_id(field, regex)
-
18
return nil unless field.config && field.config['options']
-
-
14
field.config['options'].each do |option|
-
30
if option['code'] =~ regex || option['label'] =~ regex
-
7
return option['id']
-
end
-
end
-
nil
-
end
-
-
1
def append_star(text)
-
# When searching for a number, like 8, we don't want to search 8*:
-
# that is, we don't want to search prefixes, we want to search an exact number.
-
# That's why we don't append a start.
-
21
if text.integer?
-
3
text
-
else
-
# Lucene doesn't support searching for "foo ba*":
-
# http://wiki.apache.org/lucene-java/LuceneFAQ#Can_I_combine_wildcard_and_phrase_search.2C_e.g._.22foo_ba.2A.22.3F
-
#
-
# So our approach here is: if just one word is looked for, we use a star, no quotes.
-
# Otherwise, we use quotes and no star.
-
-
18
if text =~ /\s/
-
3
%Q("#{text}")
-
else
-
# We do want to search prefixes for location values. This types of values comes as single words.
-
15
"#{text}*"
-
end
-
end
-
end
-
end
-
end
-
1
class ElasticSearch::SitesAdapter < Psych::Handler
-
1
IGNORE_FIELDS = %w(type created_at updated_at)
-
-
1
def initialize(listener)
-
24
@listener = listener
-
24
@source_mappings = 0
-
24
@properties_mappings = 0
-
24
@site = {}
-
24
@site[:property] = []
-
end
-
-
1
def parse(reader)
-
24
Psych::Parser.new(self).parse reader
-
end
-
-
1
def return_property(property)
-
5
@return_property = property
-
5
@site[:property] = []
-
end
-
-
1
def scalar(value, anchor, tag, plain, quoted, style)
-
1031
if value == '_source'
-
19
@in_source = true
-
1012
elsif value == '_index'
-
19
@in_index = true
-
993
elsif @in_index
-
19
value =~ /(\d+)/
-
19
@site[:collection_id] = $1.to_i
-
19
@in_index = false
-
974
elsif @in_source
-
452
if @in_properties
-
82
return unless @return_property
-
38
if @current_property
-
20
if @current_property == @return_property
-
8
@site[:property] << value.to_s
-
end
-
20
@current_property = nil if !@in_sequence
-
else
-
18
@current_property = value
-
end
-
else
-
370
if @current_property
-
166
case @current_property
-
19
when 'id' then @site[:id] = value.to_i
-
19
when 'lat' then @site[:lat] = value.to_f
-
19
when 'lon' then @site[:lng] = value.to_f
-
9
when 'name' then @site[:name] = value.to_s
-
else
-
100
@site[@current_property.to_sym] = value.to_s unless IGNORE_FIELDS.include? @current_property
-
end
-
166
@current_property = nil
-
else
-
204
case value
-
19
when 'properties' then @in_properties = true
-
185
else @current_property = value
-
end
-
end
-
end
-
end
-
end
-
-
1
def start_sequence(anchor, tag, implicit, style)
-
30
if @return_property && @current_property == @return_property
-
4
@in_sequence = true
-
4
@site[:property] = []
-
end
-
end
-
-
1
def end_sequence
-
30
@current_property = nil
-
30
@in_sequence = false
-
end
-
-
1
def start_mapping(anchor, tag, implicit, style)
-
148
if @in_source
-
57
@source_mappings += 1
-
57
@current_property = nil
-
57
if @in_properties
-
19
@properties_mappings += 1
-
end
-
end
-
end
-
-
1
def end_mapping
-
148
if @in_source
-
57
@source_mappings -= 1
-
57
if @source_mappings == 0
-
19
@in_source = false
-
19
@listener.add @site
-
19
@site[:property] = []
-
end
-
-
57
if @in_properties
-
19
@properties_mappings -= 1
-
19
@in_properties = false if @properties_mappings == 0
-
end
-
end
-
end
-
-
1
class SkipIdListener
-
1
def initialize(listener, id)
-
3
@listener = listener
-
3
@excluded_id = id
-
end
-
-
1
def add(site)
-
3
@listener.add site if @excluded_id != site[:id]
-
end
-
end
-
end
-
1
class Field < ActiveRecord::Base
-
1
include Field::Base
-
1
include Field::ElasticsearchConcern
-
1
include Field::ValidationConcern
-
1
include Field::ShpConcern
-
-
1
include HistoryConcern
-
-
1
self.inheritance_column = :kind
-
-
1
belongs_to :collection
-
1
belongs_to :layer
-
-
1
validates_presence_of :ord
-
1987
validates_inclusion_of :kind, :in => proc { kinds() }
-
1
validates_presence_of :code
-
1987
validates_exclusion_of :code, :in => proc { reserved_codes() }
-
1
validates_uniqueness_of :code, :scope => :collection_id
-
1
validates_uniqueness_of :name, :scope => :collection_id
-
-
1
serialize :config, MarshalZipSerializable
-
1
serialize :metadata
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
def self.reserved_codes
-
2014
['lat', 'long', 'name', 'resmap-id', 'last updated']
-
end
-
-
1
before_save :set_collection_id_to_layer_id, :unless => :collection_id?
-
1
def set_collection_id_to_layer_id
-
83
self.collection_id = layer.collection_id if layer
-
end
-
-
1
before_save :save_config_as_hash_not_with_indifferent_access, :if => :config?
-
1
def save_config_as_hash_not_with_indifferent_access
-
604
self.config = config.to_hash
-
-
604
self.config['options'].map!(&:to_hash) if self.config['options']
-
604
sanitize_hierarchy_items self.config['hierarchy'] if self.config['hierarchy']
-
end
-
-
1
after_create :update_collection_mapping
-
1
def update_collection_mapping
-
1959
collection.update_mapping
-
end
-
-
# inheritance_column added to json
-
1
def serializable_hash(options = {})
-
4
{ "kind" => kind }.merge super
-
end
-
-
1
class << self
-
1
def new_with_cast(*field_data, &b)
-
2021
hash = field_data.first
-
2021
kind = (field_data.first.is_a? Hash)? hash[:kind] || hash['kind'] || sti_name : sti_name
-
2021
klass = find_sti_class(kind)
-
2010
raise "Field is an abstract class and cannot be instanciated." unless (klass < self || self == klass)
-
2010
hash.delete "kind" if hash
-
2010
hash.delete :kind if hash
-
2010
klass.new_without_cast(*field_data, &b)
-
end
-
1
alias_method_chain :new, :cast
-
end
-
-
1
def self.find_sti_class(kind)
-
10882
"Field::#{kind.classify}Field".constantize
-
end
-
-
1
def self.sti_name
-
28754
from_class_name_to_underscore(name)
-
end
-
-
1
def self.inherited(subclass)
-
14
Layer.has_many "#{from_class_name_to_underscore(subclass.name)}_fields".to_sym, class_name: subclass.name
-
14
Collection.has_many "#{from_class_name_to_underscore(subclass.name)}_fields".to_sym, class_name: subclass.name
-
14
super
-
end
-
-
1
def self.from_class_name_to_underscore(name)
-
28782
underscore_kind = name.split('::').last.underscore
-
28782
match = underscore_kind.match(/(.*)_field/)
-
28782
if match
-
28782
match[1]
-
else
-
underscore_kind
-
end
-
end
-
-
1
def assign_attributes(new_attributes, options = {})
-
246
if (new_kind = (new_attributes["kind"] || new_attributes[:kind]))
-
2
if new_kind == kind
-
2
new_attributes.delete "kind"
-
2
new_attributes.delete :kind
-
else
-
raise "Cannot change field's kind"
-
end
-
end
-
246
super
-
end
-
-
1
def history_concern_foreign_key
-
1979
'field_id'
-
end
-
-
1
def default_value_for_create(collection)
-
nil
-
end
-
-
1
def default_value_for_update
-
nil
-
end
-
-
1
def value_type_description
-
7
"#{kind} values"
-
end
-
-
1
def value_hint
-
nil
-
end
-
-
1
def csv_headers(human = false)
-
74
[code]
-
end
-
-
1
def csv_values(value, human = false)
-
38
if human
-
value = decode(value) rescue value
-
[human_value(value)] rescue csv_values(value)
-
else
-
38
[Array(value).join(", ")]
-
end
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
27
"are not valid for the type #{kind}"
-
end
-
-
# Enables caching options and other info for a read-only usage
-
# of this field, so that validations and such can be performed faster.
-
1
def cache_for_read
-
end
-
-
1
private
-
-
1
def add_option_to_options(options, option)
-
460
options << { id: option['id'], name: option['name']}
-
460
if option['sub']
-
138
option['sub'].each do |sub_option|
-
238
add_option_to_options(options, sub_option)
-
end
-
end
-
end
-
-
1
def sanitize_hierarchy_items(items)
-
343
items.map! &:to_hash
-
343
items.each do |item|
-
498
sanitize_hierarchy_items item['sub'] if item['sub']
-
end
-
end
-
end
-
1
module Field::Base
-
1
extend ActiveSupport::Concern
-
-
1
BaseKinds = [
-
{ name: 'text', css_class: 'ltext', small_css_class: 'stext' },
-
{ name: 'numeric', css_class: 'lnumber', small_css_class: 'snumeric' },
-
{ name: 'yes_no', css_class: 'lyesno', small_css_class: 'syes_no' },
-
{ name: 'select_one', css_class: 'lsingleoption', small_css_class: 'sselect_one' },
-
{ name: 'select_many', css_class: 'lmultipleoptions', small_css_class: 'sselect_many' },
-
{ name: 'hierarchy', css_class: 'lhierarchy', small_css_class: 'shierarchy' },
-
{ name: 'date', css_class: 'ldate', small_css_class: 'sdate' },
-
{ name: 'site', css_class: 'lsite', small_css_class: 'ssite' },
-
{ name: 'user', css_class: 'luser', small_css_class: 'suser' },
-
{ name: 'photo', css_class: 'lbutton lphoto', small_css_class: 'sphoto' },
-
{ name: 'location', css_class: 'llocation', small_css_class: 'slocation'}]
-
-
1
BaseKinds.each do |base_kind|
-
11
class_eval %Q(def #{base_kind[:name]}?; kind == '#{base_kind[:name]}'; end)
-
end
-
-
1
module ClassMethods
-
1
def plugin_kinds
-
8316
Plugin.hooks(:field_type).index_by { |h| h[:name] }
-
end
-
-
1
def kinds
-
23892
(BaseKinds.map{|k| k[:name]} | plugin_kinds.keys).sort.freeze
-
end
-
end
-
-
1
def select_kind?
-
28
select_one? || select_many?
-
end
-
-
1
def plugin?
-
15
self.class.plugin_kinds.has_key? kind
-
end
-
-
1
def stored_as_date?
-
1131
date?
-
end
-
-
1
def stored_as_number?
-
7
numeric? || select_one? || select_many? || hierarchy?
-
end
-
-
1
def stored_as_double?
-
1791
numeric?
-
end
-
-
1
def stored_as_long?
-
2210
select_one? || select_many?
-
end
-
-
1
def stored_as_floating_point?
-
numeric? && allow_decimals?
-
end
-
1
def allow_decimals?
-
977
config && (config[:allows_decimals] == "true" || config["allows_decimals"] == "true")
-
end
-
-
1
def strongly_type(value)
-
7
if stored_as_number?
-
3
value.is_a?(Array) ? value.map(&:to_i_or_f) : value.to_s.to_i_or_f
-
else
-
4
decode value
-
end
-
end
-
-
1
def api_value(value)
-
110
if yes_no?
-
9
Field.yes?(value)
-
101
elsif select_one?
-
25
option = config['options'].find { |o| o['id'] == value }
-
12
return option ? option['code'] : value
-
89
elsif select_many?
-
13
if value.is_a? Array
-
13
return value.map do |val|
-
63
option = config['options'].find { |o| o['id'] == val }
-
25
option ? option['code'] : val
-
end
-
else
-
return value
-
end
-
76
elsif hierarchy?
-
20
return find_hierarchy_name_by_id(value)
-
56
elsif date?
-
12
return Time.iso8601(value).strftime("%m/%d/%Y")
-
else
-
44
return value
-
end
-
end
-
-
1
def human_value(value)
-
3
if select_one?
-
option = config['options'].find { |o| o['id'] == value }
-
return option ? option['label'] : value
-
3
elsif select_many?
-
if value.is_a? Array
-
return value.map do |val|
-
option = config['options'].find { |o| o['id'] == val }
-
option ? option['label'] : val
-
end.join ', '
-
else
-
return value
-
end
-
3
elsif hierarchy?
-
return find_hierarchy_value value
-
3
elsif date?
-
1
return Time.iso8601(value).strftime("%m/%d/%Y")
-
else
-
2
return value
-
end
-
end
-
-
1
def sample_value(user = nil)
-
15
if plugin?
-
2
kind_config = self.class.plugin_kinds()[kind]
-
2
if kind_config.has_key? :sample_value
-
2
return kind_config[:sample_value]
-
else
-
return ''
-
end
-
end
-
-
13
if text?
-
2
value = 'sample text value'
-
elsif numeric?
-
1
value = -39.2
-
elsif date?
-
2
value = Field::DateField.new.decode('4/23/1851')
-
elsif user?
-
1
return '' if user.nil?
-
1
value = user.email
-
elsif select_one?
-
2
options = config['options']
-
2
return '' if options.nil? or options.length == 0
-
1
value = config['options'][0]['id']
-
elsif select_many?
-
3
options = config['options']
-
3
return '' if options.nil? or options.length == 0
-
2
if options.length == 1
-
value = [options[0]['id']]
-
else
-
2
value = [options[0]['id'], options[1]['id']]
-
end
-
elsif hierarchy?
-
2
@hierarchy_items_map ||= create_hierarchy_items_map
-
2
keys = @hierarchy_items_map.keys
-
2
return '' if keys.length == 0
-
1
value = keys.first
-
else
-
return ''
-
end
-
10
api_value value
-
end
-
-
1
private
-
-
1
def find_hierarchy_value(value)
-
@hierarchy_items_map ||= create_hierarchy_items_map
-
item = @hierarchy_items_map[value]
-
item ? hierarchy_item_to_s(item) : value
-
end
-
-
1
def create_hierarchy_items_map(map = {}, items = config['hierarchy'] || [], parent = nil)
-
3
items.each do |item|
-
2
map_item = {'name' => item['name'], 'parent' => parent}
-
2
map[item['id']] = map_item
-
2
create_hierarchy_items_map map, item['sub'], map_item if item['sub'].present?
-
end
-
3
map
-
end
-
-
1
def hierarchy_item_to_s(str = '', item)
-
if item['parent']
-
hierarchy_item_to_s str, item['parent']
-
str << ' - '
-
end
-
str << item['name']
-
str
-
end
-
end
-
1
class Field::DateField < Field
-
-
1
def value_type_description
-
3
"dates"
-
end
-
-
1
def value_hint
-
3
"Example of valid date: 1/25/2013."
-
end
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
6
validated_value = {}
-
6
iso_date_from = decode(parse_date_from(value))
-
4
validated_value[:date_from] = iso_date_from if valid_value?(iso_date_from)
-
4
iso_date_to = decode(parse_date_to(value))
-
4
validated_value[:date_to] = iso_date_to if valid_value?(iso_date_to)
-
4
validated_value
-
end
-
-
1
def decode(m_d_y_value)
-
32
begin
-
32
m_d_y_value.present? ? convert_to_iso8601_string(m_d_y_value) : nil
-
rescue
-
11
raise invalid_field_message()
-
end
-
end
-
-
1
def decode_from_ui(value)
-
3
begin
-
3
decode(value)
-
rescue
-
2
value
-
end
-
end
-
-
1
def decode_fred(iso_string_value)
-
# FRED API uses iso8601 format in updates, so we dont need to decode any value
-
# If this value is not an iso string, an exception will be thrown in the site's validation.
-
iso_string_value
-
end
-
-
1
def valid_value?(value, site = nil)
-
79
begin
-
79
time = Time.iso8601(value)
-
78
iso_value = format_date_iso_string(time)
-
78
raise "invalid" unless iso_value == value
-
rescue
-
1
raise invalid_field_message()
-
end
-
78
true
-
end
-
-
1
def parse_date(m_d_y_value)
-
32
Time.strptime m_d_y_value, '%m/%d/%Y'
-
end
-
-
1
private
-
-
1
def invalid_field_message()
-
13
"Invalid date value in field #{code}"
-
end
-
-
1
def convert_to_iso8601_string(m_d_y_value)
-
31
format_date_iso_string(parse_date(m_d_y_value))
-
end
-
-
1
def format_date_iso_string(time)
-
98
time.strftime "%Y-%m-%dT00:00:00Z"
-
end
-
-
1
def parse_date_from(value)
-
7
match = (value.match /(.*),/)
-
7
if match.nil?
-
1
raise invalid_field_message
-
end
-
6
match.captures[0]
-
end
-
-
1
def parse_date_to(value)
-
5
match = (value.match /,(.*)/)
-
5
if match.nil?
-
raise invalid_field_message
-
end
-
5
match.captures[0]
-
end
-
-
-
end
-
1
module Field::ElasticsearchConcern
-
1
extend ActiveSupport::Concern
-
-
1
def index_mapping
-
case
-
when kind == 'yes_no'
-
157
{ type: :boolean }
-
when stored_as_long?
-
419
{ type: :long }
-
when stored_as_double?
-
660
{ type: :double }
-
when stored_as_date?
-
190
{ type: :date }
-
else
-
941
{ type: :string, index: :not_analyzed }
-
2367
end
-
end
-
-
# Returns the code to store this field in Elastic Search
-
1
def es_code
-
16792
id.to_s
-
end
-
-
1
module ClassMethods
-
1
def where_es_code_is(es_code)
-
20
where(:id => es_code.to_i).first
-
end
-
end
-
end
-
1
class Field::HierarchyField < Field
-
1
def value_type_description
-
2
"values that can be found in the defined hierarchy"
-
end
-
-
1
def value_hint
-
2
"Some valid values for this hierarchy are: #{hierarchy_options_names_samples}."
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
3
"don't exist in the corresponding hierarchy"
-
end
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
9
check_presence_of_value(value)
-
9
decode_hierarchy_option(value, use_codes_instead_of_es_codes)
-
end
-
-
1
def decode(hierarchy_name)
-
13
if hierarchy_code = find_hierarchy_id_by_name(hierarchy_name)
-
9
hierarchy_code
-
else
-
4
raise invalid_field_message()
-
end
-
end
-
-
1
def invalid_field_message()
-
5
"Invalid hierarchy option in field #{code}"
-
end
-
-
1
def valid_value?(hierarchy_code, site = nil)
-
480
if (hierarchy_options_codes.map{|o|o.to_s}).include?(hierarchy_code.to_s)
-
143
true
-
else
-
1
raise invalid_field_message
-
end
-
end
-
-
1
def descendants_of_in_hierarchy(parent, use_codes_instead_of_es_codes)
-
4
if use_codes_instead_of_es_codes
-
2
parent_id = find_hierarchy_id_by_name(parent)
-
else
-
2
parent_id = parent
-
end
-
# valid_value?(parent_id)
-
4
options = []
-
4
add_option_to_options options, find_hierarchy_item_by_id(parent_id)
-
# if use_codes_instead_of_es_codes
-
# options.map { |item| item[:name] }
-
# else
-
12
options.map { |item| item[:id] }
-
# end
-
end
-
-
1
def cache_for_read
-
56
@cache_for_read = true
-
end
-
-
1
def hierarchy_options_codes
-
494
hierarchy_options.map {|option| option[:id]}
-
end
-
-
1
def hierarchy_options_names
-
8
hierarchy_options.map {|option| option[:name]}
-
end
-
-
1
def hierarchy_options_names_samples
-
2
hierarchy_options_names.take(3).join(", ")
-
end
-
-
1
def hierarchy_options
-
189
if @cache_for_read && @options_in_cache
-
4
return @options_in_cache
-
end
-
-
185
options = []
-
185
config['hierarchy'].each do |option|
-
218
add_option_to_options(options, option)
-
end
-
-
185
if @cache_for_read
-
12
@options_in_cache = options
-
end
-
-
185
options
-
end
-
-
1
def find_hierarchy_id_by_name(value)
-
20
if @cache_for_read
-
11
@options_by_name ||= hierarchy_options.each_with_object({}) { |opt, hash| hash[opt[:name]] = opt[:id] }
-
5
return @options_by_name[value]
-
end
-
-
41
option = hierarchy_options.find { |opt| opt[:name] == value }
-
15
option[:id] if option
-
end
-
-
1
def find_hierarchy_name_by_id(value)
-
21
if @cache_for_read
-
49
@options_by_id ||= hierarchy_options.each_with_object({}) { |opt, hash| hash[opt[:id]] = opt[:name] }
-
19
return @options_by_id[value]
-
end
-
-
6
option = hierarchy_options.find { |opt| opt[:id] == value }
-
2
option[:name] if option
-
end
-
-
1
def find_hierarchy_by_id(value)
-
4
if @cache_for_read
-
@options_by_id ||= hierarchy_options.each_with_object({}) { |opt, hash| hash[opt[:id]] = opt[:name] }
-
return @options_by_id[value]
-
end
-
14
option = hierarchy_options.find { |opt| opt[:id] == value }
-
4
option if option
-
end
-
-
1
def find_hierarchy_by_name(value)
-
2
if @cache_for_read
-
@options_by_id ||= hierarchy_options.each_with_object({}) { |opt, hash| hash[opt[:name]] = opt[:id] }
-
return @options_by_id[value]
-
end
-
4
option = hierarchy_options.find { |opt| opt[:name] == value }
-
2
option if option
-
end
-
-
1
def transform
-
field_hierarchy = {}
-
field_hierarchy["hierarchy"] = inject_parent_id(self.config["hierarchy"], nil, 0) if self.config["hierarchy"]
-
return field_hierarchy
-
end
-
-
1
def get_longest_depth
-
max = 0
-
self.hierarchy_options.each do |item|
-
if max < item[:level].to_i
-
max = item[:level].to_i
-
end
-
end
-
max
-
end
-
-
1
private
-
-
1
def inject_parent_id hierarchy, parent_id, level
-
level = level + 1
-
hierarchy.each do |item|
-
item["parent_id"] = parent_id
-
item["level"] = level
-
if item["sub"]
-
inject_parent_id item["sub"], item["id"], level
-
end
-
end
-
level = level - 1
-
hierarchy
-
end
-
-
1
def find_hierarchy_item_by_id(id, start_at = config['hierarchy'])
-
5
start_at.each do |item|
-
6
return item if item['id'].to_s == id.to_s
-
2
if item.has_key? 'sub'
-
1
found = find_hierarchy_item_by_id(id, item['sub'])
-
1
return found unless found.nil?
-
end
-
end
-
nil
-
end
-
-
# TODO: Integrate with decode used in update
-
1
def decode_hierarchy_option(array_value, use_codes_instead_of_es_codes)
-
9
if !array_value.kind_of?(Array)
-
9
array_value = [array_value]
-
end
-
9
value_ids = []
-
9
array_value.each do |value|
-
9
value_id = check_option_exists(value, use_codes_instead_of_es_codes)
-
8
value_ids << value_id
-
end
-
8
value_ids
-
end
-
-
1
def check_option_exists(value, use_codes_instead_of_es_codes)
-
9
value_id = nil
-
9
if use_codes_instead_of_es_codes
-
5
value_id = find_hierarchy_id_by_name(value)
-
5
value_id = value if value_id.nil? && !find_hierarchy_name_by_id(value).nil?
-
else
-
14
value_id = value unless !hierarchy_options_codes.map{|o|o.to_s}.include? value.to_s
-
end
-
9
raise "Invalid hierarchy option in field #{code}" if value_id.nil?
-
8
value_id
-
end
-
-
end
-
1
class Field::LocationField < Field
-
-
end
-
1
class Field::NumericField < Field
-
1
def value_type_description
-
7
"numeric values"
-
end
-
-
1
def value_hint
-
7
"Values must be integers."
-
end
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
32
check_presence_of_value(value)
-
32
valid_format? value
-
30
standadrize(value)
-
end
-
-
1
def standadrize(value)
-
470
if allow_decimals?
-
3
value.to_f
-
else
-
467
value.to_i
-
end
-
end
-
-
1
def decode(value)
-
28
if allow_decimals?
-
3
raise allows_decimals_message unless value.real?
-
3
Float(value)
-
else
-
25
raise not_allow_decimals_message unless value.integer?
-
16
Integer(value)
-
end
-
end
-
-
1
def valid_format?(value)
-
32
if allow_decimals?
-
raise allows_decimals_message unless value.real?
-
else
-
32
raise not_allow_decimals_message if !value.integer? && value.real?
-
32
raise invalid_field_message unless value.integer?
-
end
-
end
-
-
1
def valid_value?(value, site = nil)
-
444
if allow_decimals?
-
5
raise allows_decimals_message unless value.real?
-
else
-
439
raise not_allow_decimals_message if !value.integer? && value.real?
-
439
raise invalid_field_message unless value.integer?
-
end
-
443
if config and config['range']
-
validate_range(value)
-
end
-
443
true
-
end
-
-
1
def validate_range(value)
-
if config['range']['minimum'] && config['range']['maximum'] && config['range']['minimum'] <= config['range']['maximum']
-
unless value.to_f >= config['range']['minimum'] && value.to_f <= config['range']['maximum']
-
raise "Invalid value, value must be in the range of (#{config['range']['minimum']}-#{config['range']['maximum']})"
-
end
-
end
-
-
if config['range']['minimum']
-
raise "Invalid value, value must be greater than or equal #{config['range']['minimum']}" unless value.to_f >= config['range']['minimum']
-
end
-
-
if config['range']['maximum']
-
raise "Invalid value, value must be less than or equal #{config['range']['maximum']}" unless value.to_f <= config['range']['maximum']
-
end
-
end
-
-
1
def to_dbf_field
-
2
length, decimal = allow_decimals? ? [8, 1] : [4, 0]
-
2
Collection.dbf_field_for self.code, type: 'N', length: length, decimal: decimal
-
end
-
-
1
private
-
-
1
def invalid_field_message()
-
12
"Invalid numeric value in field #{code}"
-
end
-
-
1
def allows_decimals_message()
-
"#{invalid_field_message}. This numeric field is configured to allow decimal values."
-
end
-
-
1
def not_allow_decimals_message()
-
9
"#{invalid_field_message}. This numeric field is configured not to allow decimal values."
-
end
-
-
1
def invalid_range()
-
"Invalid range"
-
end
-
end
-
1
class Field::PhotoField < Field
-
1
def value_type_description
-
"photos"
-
end
-
-
1
def value_hint
-
"Path to photo."
-
end
-
-
# params: value is 2-element array
-
# value[0] - is the filename
-
# value[1] - is the binary string of the image
-
1
def decode_from_ui(value)
-
Site::UploadUtils.uploadSingleFile value[0], Base64.decode64(value[1]) if value[1]
-
value[0]
-
end
-
end
-
1
class Field::SelectManyField < Field
-
1
def value_type_description
-
1
"option values"
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
2
"don't match any existing option"
-
end
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
3
check_presence_of_value(value)
-
3
query_value(value, use_codes_instead_of_es_codes)
-
end
-
-
1
def standadrize(value)
-
68
if value.kind_of?(Array)
-
65
option_list = value
-
else
-
3
option_list = value.to_s.split(%r{\s*,\s*})
-
end
-
68
option_list.map(&:to_i)
-
end
-
-
1
def decode(option_values)
-
16
if option_values.kind_of?(Array)
-
3
option_values = option_values
-
else
-
13
option_values = option_values.to_s.split(%r{\s*,\s*})
-
end
-
16
value_ids = []
-
16
option_values.each do |value|
-
21
value_id = decode_option(value)
-
17
value_ids << value_id
-
end
-
12
value_ids
-
end
-
-
1
def valid_value?(option_codes, site = nil)
-
70
if option_codes.kind_of?(Array)
-
67
option_codes_list = option_codes
-
else
-
3
option_codes_list = option_codes.to_s.split(%r{\s*,\s*})
-
end
-
70
option_codes_list.each do |option|
-
120
check_option_exists(option)
-
end
-
end
-
-
1
private
-
-
# TODO: Integrate with decode used in update
-
1
def query_value(value, use_codes_instead_of_es_codes)
-
3
value_id = nil
-
3
if use_codes_instead_of_es_codes
-
2
config['options'].each do |option|
-
4
value_id = option['id'] if option['label'] == value || option['code'] == value
-
end
-
2
if value_id.nil?
-
1
config['options'].each do |option|
-
2
value_id = option['id'] if option['id'].to_s == value.to_s
-
end
-
end
-
else
-
1
config['options'].each do |option|
-
2
value_id = option['id'] if option['id'].to_s == value.to_s
-
end
-
end
-
3
raise "Invalid option in field #{code}" if value_id.nil?
-
2
value_id
-
end
-
-
1
def invalid_field_message(value)
-
6
"Invalid option '#{value}' in field #{code}"
-
end
-
-
1
def decode_option(value)
-
21
value_id = nil
-
21
config['options'].each do |option|
-
42
value_id = option['id'] if option['label'] == value || option['code'] == value
-
end
-
-
21
if value_id.nil?
-
4
raise invalid_field_message(value)
-
else
-
17
value_id
-
end
-
end
-
-
1
def check_option_exists(value)
-
120
exists = false
-
120
config['options'].each do |option|
-
240
exists = true if option['id'].to_s == value.to_s
-
end
-
120
raise invalid_field_message(value) if !exists
-
118
exists
-
end
-
-
end
-
1
class Field::SelectOneField < Field
-
1
def value_type_description
-
1
"option values"
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
2
"don't match any existing option"
-
end
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
4
return nil unless value.present?
-
4
query_value(value, use_codes_instead_of_es_codes)
-
end
-
-
1
def decode(option_label_or_code)
-
18
decode_option(option_label_or_code)
-
end
-
-
1
def standadrize(value)
-
131
value.to_i
-
end
-
-
1
def valid_value?(option_code, site=nil)
-
134
if @cache_for_read
-
1
raise invalid_field_message unless @options_by_id_in_cache.values.include?(option_code)
-
else
-
133
check_option_exists(option_code)
-
end
-
end
-
-
1
def cache_for_read
-
57
@cache_for_read = true
-
end
-
-
1
private
-
-
# TODO: Integrate with decode used in update
-
1
def query_value(value, use_codes_instead_of_es_codes)
-
4
if @cache_for_read && !@options_by_code_or_label_in_cache
-
prepare_cache_for_read
-
end
-
-
4
value_id = nil
-
4
if use_codes_instead_of_es_codes
-
3
if @cache_for_read
-
value_id = @options_by_code_or_label_in_cache[value.to_s]
-
else
-
3
config['options'].each do |option|
-
7
value_id = option['id'] if option['label'] == value || option['code'] == value
-
end
-
3
if value_id.nil?
-
1
config['options'].each do |option|
-
2
value_id = option['id'] if option['id'].to_s == value.to_s
-
end
-
end
-
end
-
else
-
1
if @cache_for_read
-
value_id = @options_by_id_in_cache[value.to_s]
-
else
-
1
config['options'].each do |option|
-
2
value_id = option['id'] if option['id'].to_s == value.to_s
-
end
-
end
-
end
-
4
raise "Invalid option in field #{code}" if value_id.nil?
-
3
value_id
-
end
-
-
1
def check_option_exists(value)
-
133
exists = false
-
133
config['options'].each do |option|
-
316
exists = true if option['id'].to_s == value.to_s
-
end
-
133
raise invalid_field_message if !exists
-
132
exists
-
end
-
-
1
def invalid_field_message()
-
4
"Invalid option in field #{code}"
-
end
-
-
1
def decode_option(value)
-
18
if @cache_for_read && !@options_by_code_or_label_in_cache
-
1
prepare_cache_for_read
-
end
-
18
value_id = nil
-
18
if @cache_for_read
-
3
value_id = @options_by_code_or_label_in_cache[value.to_s]
-
else
-
15
config['options'].each do |option|
-
27
value_id = option['id'] if option['label'] == value || option['code'] == value
-
end
-
end
-
18
if value_id.nil?
-
3
raise invalid_field_message
-
else
-
15
value_id
-
end
-
end
-
-
1
def prepare_cache_for_read
-
1
@options_by_code_or_label_in_cache = {}
-
1
@options_by_id_in_cache = {}
-
-
1
config['options'].each do |option|
-
2
@options_by_code_or_label_in_cache[option['code'].to_s] = option['id']
-
2
@options_by_code_or_label_in_cache[option['label'].to_s] = option['id']
-
2
@options_by_id_in_cache[option['id'].to_s] = option['id']
-
end
-
end
-
-
end
-
1
require 'dbf'
-
-
1
module Field::ShpConcern
-
1
extend ActiveSupport::Concern
-
-
1
def to_dbf_field
-
3
Collection.dbf_field_for self.code, type: 'C', length: 100
-
end
-
end
-
1
class Field::SiteField < Field
-
1
def value_type_description
-
2
"site ids"
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
3
"don't match any existing site id in this collection"
-
end
-
-
1
def valid_value?(site_id, site=nil)
-
40
check_site_exists(site_id)
-
end
-
-
-
1
private
-
-
1
def check_site_exists(site_id)
-
84
site_ids = collection.sites.map{|s| s.id.to_s}
-
-
40
if !site_ids.include? site_id.to_s
-
6
raise "Non-existent site-id in field #{code}"
-
end
-
34
true
-
end
-
-
end
-
1
class Field::TextField < Field
-
-
end
-
1
class Field::UserField < Field
-
1
def value_type_description
-
2
"email addresses"
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
3
"don't match any email address of a member of this collection"
-
end
-
-
1
def valid_value?(user_email, site=nil)
-
36
check_user_exists(user_email)
-
end
-
-
1
private
-
-
1
def check_user_exists(user_email)
-
# debugger
-
# user_emails = collection.users.map {|u| u.email}
-
36
user_emails = collection.memberships.select(:email).joins(:user).map(&:email)
-
36
if !user_emails.include? user_email
-
5
raise "Non-existent user email address in field #{code}"
-
end
-
31
true
-
end
-
end
-
1
module Field::ValidationConcern
-
1
extend ActiveSupport::Concern
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
7
check_presence_of_value(value)
-
7
value
-
end
-
-
1
def parse_for_query(value, use_codes_instead_of_es_codes = false)
-
35
if !value.is_a?(Array)
-
29
value = [value]
-
end
-
-
72
parsed = value.map { |v| apply_format_query_validation(v, use_codes_instead_of_es_codes) }.flatten
-
-
30
if parsed.count == 1
-
28
parsed.first
-
else
-
2
parsed
-
end
-
end
-
-
1
def apply_format_and_validate(value, use_codes_instead_of_es_codes, collection, site = nil)
-
146
decoded_value = value.blank? ? nil : decode(value)
-
118
if decoded_value
-
104
standadrize(decoded_value) if valid_value?(decoded_value, site)
-
else
-
14
decoded_value
-
end
-
end
-
-
1
def decode(value)
-
46
value
-
end
-
-
1
def valid_value?(value, site = nil)
-
347
true
-
end
-
-
1
def standadrize(value)
-
633
value
-
end
-
-
1
def decode_from_ui(value)
-
38
value
-
end
-
-
1
def decode_fred(value)
-
decode(value)
-
end
-
-
1
module ClassMethods
-
1
def yes?(value)
-
31
value == true || value == 1 || !!(value =~ /\A(yes|true|1)\Z/i)
-
end
-
end
-
-
1
private
-
-
1
def check_presence_of_value(value)
-
53
raise "Missing #{code} value" if value.blank?
-
end
-
-
-
end
-
1
class Field::YesNoField < Field
-
-
1
def apply_format_query_validation(value, use_codes_instead_of_es_codes = false)
-
2
check_presence_of_value(value)
-
2
Field.yes?(value)
-
end
-
-
1
def decode(value)
-
14
Field.yes?(value)
-
end
-
-
1
def decode_from_ui value
-
decode value
-
end
-
-
1
def default_value_for_update
-
if config && Field.yes?(config['auto_reset'])
-
false
-
else
-
nil
-
end
-
end
-
-
end
-
1
class FieldHistory < ActiveRecord::Base
-
1
include Field::Base
-
1
include Field::ElasticsearchConcern
-
-
1
belongs_to :field
-
1
belongs_to :collection
-
1
belongs_to :layer
-
-
1
serialize :config
-
1
serialize :metadata
-
-
1
def es_code
-
27
field_id.to_s
-
end
-
-
1
def as_json(options = {})
-
{ code: code, collection_id: collection_id, config: config, id: field_id, kind: kind, layer_id: layer_id, name: name, ord: ord}
-
end
-
-
1
def cache_for_read
-
4
safe_field.cache_for_read
-
end
-
-
1
def api_value(value)
-
safe_field.api_value(value)
-
end
-
-
1
def human_value(value)
-
safe_field.human_value(value)
-
end
-
-
1
def allow_decimals?
-
safe_field.allow_decimals?
-
end
-
-
1
def safe_field
-
4
field = field()
-
4
return field if field
-
-
@fake_field ||= Field.new attributes.except("id", "valid_since", "valid_to", "field_id", "version")
-
end
-
-
end
-
1
class HashParser
-
1
def self.from_xml_file(xml)
-
5
raise "missing xml file" if xml.nil?
-
4
begin
-
4
submission = Hash.from_xml(xml.read)
-
rescue
-
1
raise "invalid xml format"
-
end
-
end
-
end
-
1
module HistoryConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
3
history_class_name = "#{name}History"
-
-
3
after_create :create_history
-
3
after_update :expire_current_history_and_create_new_one
-
3
before_destroy :expire_current_history
-
-
3
has_many :histories, :class_name => history_class_name
-
-
3
class << history_class_name.constantize
-
3
def at_date(date)
-
92
where "#{table_name}.valid_since <= :date && (:date < #{table_name}.valid_to || #{table_name}.valid_to is null)", date: date
-
end
-
end
-
end
-
-
1
def create_history
-
3161
history = histories.new
-
3161
attributes.each_pair do |att_name, att_value|
-
41556
unless ['id', 'created_at', 'updated_at', 'device_id', 'external_id',"is_mandatory","is_enable_field_logic","is_enable_range"].include? att_name
-
24742
history[att_name] = att_value
-
end
-
end
-
3161
history["valid_since"] = updated_at
-
3161
history[self.history_concern_foreign_key] = id
-
3161
history.save!
-
3161
history
-
end
-
-
1
def current_history
-
120
histories.where(valid_to: nil).first
-
end
-
-
1
def expire_current_history_and_create_new_one
-
90
expire_current_history updated_at
-
90
create_history
-
end
-
-
1
def expire_current_history(valid_to = Time.now)
-
114
current_history.try :update_attributes!, valid_to: valid_to
-
end
-
end
-
1
class Identity < ActiveRecord::Base
-
1
attr_accessible :provider, :token, :user_id
-
-
1
belongs_to :user
-
end
-
1
class ImportJob < ActiveRecord::Base
-
# The status field captures the lifecycle of an ImportJob. Currently it is:
-
#
-
# :file_uploaded => :pending
-
# => :in_progress
-
# => :finished
-
# => :failed
-
# => :canceled_by_user
-
#
-
# :file_uploaded: a CSV file has been uploaded, but the import process for it hasn't been executed yet.
-
# :pending: there's an import job enqueued in Resque waiting to be processed.
-
# :in_progress: the import is being processed by the worker.
-
# :finished: the import was already processed.
-
# :canceled_by_user: the user canceled the import when the job was in status pending. This job will not be processed.
-
-
# :finished_at is nil until the ImportJob reaches the :finished status, when its assigned Time.now
-
-
1
attr_accessible :finished_at, :original_filename, :status
-
-
1
belongs_to :user
-
1
belongs_to :collection
-
-
1
def pending
-
51
Rails.logger.error "Inconsistent status for job with id #{self.id}. Should be in status 'file_uploaded' before marking it as 'pending'" unless self.status_file_uploaded?
-
51
self.status = :pending
-
51
self.save!
-
end
-
-
1
def canceled_by_user
-
Rails.logger.error "Inconsistent status for job with id #{self.id}. Should be in status 'pending' before marking it as 'canceled'" unless self.status_pending?
-
self.status = :canceled_by_user
-
self.save!
-
end
-
-
1
def in_progress
-
19
Rails.logger.error "Inconsistent status for job with id #{self.id}. Should be in status 'pending' before marking it as 'in_progress'" unless self.status_pending?
-
19
self.status = :in_progress
-
19
self.save!
-
end
-
-
1
def self.uploaded(original_filename, user, collection)
-
54
j = ImportJob.new :original_filename => original_filename, :status => :file_uploaded
-
54
j.user = user
-
54
j.collection = collection
-
54
j.save!
-
end
-
-
1
def self.last_for(user, collection)
-
107
user = user.id if user.is_a?(User)
-
107
collection = collection.id if collection.is_a?(Collection)
-
-
107
ImportJob.where(:collection_id => collection, :user_id => user).last
-
end
-
-
1
def finish
-
18
Rails.logger.error "Inconsistent status for job with id #{self.id}. Should be in status 'in_progress' before marking it as 'finished'" unless self.status_in_progress?
-
18
self.status = :finished
-
18
self.finished_at = Time.now
-
18
self.save!
-
end
-
-
1
def failed(exception)
-
Rails.logger.error "Inconsistent status for job with id #{self.id}. Should be in status 'in_progress' before marking it as 'failed'" unless self.status_in_progress?
-
self.status = :failed
-
self.exception = "#{exception.message}\n#{exception.backtrace.join "\n"}"
-
self.finished_at = Time.now
-
self.save!
-
end
-
-
1
[:file_uploaded, :pending, :in_progress, :finished, :failed, :canceled_by_user].each do |status_value|
-
6
class_eval %Q(def status_#{status_value.to_s}?; self.status == '#{status_value.to_s}'; end)
-
end
-
-
end
-
1
class ImportWizard
-
1
TmpDir = "#{Rails.root}/tmp/import_wizard"
-
-
1
class << self
-
1
def enqueue_job(user, collection, columns_spec)
-
mark_job_as_pending user, collection
-
-
# Enqueue job with user_id, collection_id, serialized column_spec
-
Resque.enqueue ImportTask, user.id, collection.id, columns_spec
-
end
-
-
1
def cancel_pending_jobs(user, collection)
-
mark_job_as_canceled_by_user(user, collection)
-
delete_file(user, collection)
-
end
-
-
1
def import(user, collection, original_filename, contents)
-
# Store representation of import job in database to enable status tracking later
-
54
ImportJob.uploaded original_filename, user, collection
-
-
54
FileUtils.mkdir_p TmpDir
-
-
54
raise "Invalid file format. Only CSV files are allowed." unless File.extname(original_filename) == '.csv'
-
-
53
begin
-
106
File.open(file_for(user, collection), "wb") { |file| file << contents }
-
53
csv = read_csv_for(user, collection)
-
194
raise CSV::MalformedCSVError, "all rows must have the same number of columns." unless csv.all?{|e| e.count == csv[0].count}
-
1
rescue CSV::MalformedCSVError => ex
-
1
raise "The file is not a valid CSV: #{ex.message}"
-
end
-
end
-
-
1
def validate_sites_with_columns(user, collection, columns_spec)
-
91
columns_spec.map!{|c| c.with_indifferent_access}
-
28
csv = read_csv_for(user, collection)
-
28
csv_columns = csv[1.. -1].transpose
-
-
28
validated_data = {}
-
28
validated_data[:sites] = get_sites(csv, user, collection, columns_spec, 1)
-
28
validated_data[:sites_count] = csv.length - 1
-
-
91
csv[0].map! { |r| r.strip if r }
-
-
28
validated_data[:errors] = calculate_errors(user, collection, columns_spec, csv_columns, csv[0])
-
# TODO: implement pagination
-
28
validated_data
-
end
-
-
1
def calculate_errors(user, collection, columns_spec, csv_columns, header)
-
#Add index to each column spec
-
28
columns_spec.each_with_index do |column_spec, column_index|
-
63
column_spec[:index] = column_index
-
end
-
-
28
sites_errors = {}
-
-
# Columns validation
-
-
483
proc_select_new_fields = Proc.new{columns_spec.select{|spec| spec[:use_as].to_s == 'new_field'}}
-
28
sites_errors[:duplicated_code] = calculate_duplicated(proc_select_new_fields, 'code')
-
28
sites_errors[:duplicated_label] = calculate_duplicated(proc_select_new_fields, 'label')
-
28
sites_errors[:missing_label] = calculate_missing(proc_select_new_fields, 'label')
-
28
sites_errors[:missing_code] = calculate_missing(proc_select_new_fields, 'code')
-
-
28
sites_errors[:reserved_code] = calculate_reserved_code(proc_select_new_fields)
-
-
28
collection_fields = collection.fields(:include => :layer)
-
28
collection_fields.each(&:cache_for_read)
-
-
28
sites_errors[:existing_code] = calculate_existing(columns_spec, collection_fields, 'code')
-
28
sites_errors[:existing_label] = calculate_existing(columns_spec, collection_fields, 'label')
-
-
# Calculate duplicated usage for default fields (lat, lng, id, name)
-
119
proc_default_usages = Proc.new{columns_spec.reject{|spec| spec[:use_as].to_s == 'new_field' || spec[:use_as].to_s == 'existing_field' || spec[:use_as].to_s == 'ignore'}}
-
28
sites_errors[:duplicated_usage] = calculate_duplicated(proc_default_usages, :use_as)
-
# Add duplicated-usage-error for existing_fields
-
119
proc_existing_fields = Proc.new{columns_spec.select{|spec| spec[:use_as].to_s == 'existing_field'}}
-
28
sites_errors[:duplicated_usage].update(calculate_duplicated(proc_existing_fields, :field_id))
-
-
# Name is mandatory
-
87
sites_errors[:missing_name] = {:use_as => 'name'} if !(columns_spec.any?{|spec| spec[:use_as].to_s == 'name'})
-
-
91
columns_used_as_id = columns_spec.select{|spec| spec[:use_as].to_s == 'id'}
-
# Only one column will be marked to be used as id
-
28
csv_column_used_as_id = csv_columns[columns_used_as_id.first[:index]] if columns_used_as_id.length > 0
-
31
sites_errors[:non_existent_site_id] = calculate_non_existent_site_id(collection.sites.map{|s| s.id.to_s}, csv_column_used_as_id, columns_used_as_id.first[:index]) if columns_used_as_id.length > 0
-
-
28
sites_errors[:data_errors] = []
-
28
sites_errors[:hierarchy_field_found] = []
-
-
# Rows validation
-
-
28
csv_columns.each_with_index do |csv_column, csv_column_number|
-
62
column_spec = columns_spec[csv_column_number]
-
-
62
if column_spec[:use_as].to_s == 'new_field' && column_spec[:kind].to_s == 'hierarchy'
-
1
sites_errors[:hierarchy_field_found] = add_new_hierarchy_error(csv_column_number, sites_errors[:hierarchy_field_found])
-
elsif column_spec[:use_as].to_s == 'new_field' || column_spec[:use_as].to_s == 'existing_field'
-
42
errors_for_column = validate_column(user, collection, column_spec, collection_fields, csv_column, csv_column_number)
-
42
sites_errors[:data_errors].concat(errors_for_column)
-
end
-
end
-
-
28
sites_errors
-
end
-
-
1
def add_new_hierarchy_error(csv_column_number, hierarchy_errors)
-
1
if hierarchy_errors.length >0 && hierarchy_errors[0][:new_hierarchy_columns].length >0
-
hierarchy_errors[0][:new_hierarchy_columns] << csv_column_number
-
else
-
1
hierarchy_errors = [{:new_hierarchy_columns => [csv_column_number]}]
-
end
-
1
hierarchy_errors
-
end
-
-
1
def get_sites(csv, user, collection, columns_spec, page)
-
28
csv_columns = csv[1 .. 10]
-
28
processed_csv_columns = []
-
28
csv_columns.each do |csv_column|
-
145
processed_csv_columns << csv_column.map{|csv_field_value| {value: csv_field_value} }
-
end
-
28
processed_csv_columns
-
end
-
-
1
def guess_columns_spec(user, collection)
-
8
rows = []
-
8
CSV.foreach(file_for user, collection) do |row|
-
21
rows << row
-
end
-
8
to_columns collection, rows, user.admins?(collection)
-
end
-
-
1
def execute(user, collection, columns_spec)
-
#Execute may be called with actual user and collection entities, or their ids.
-
19
if !(user.is_a?(User) && collection.is_a?(Collection))
-
#If the method's been called with ids instead of entities
-
user = User.find(user)
-
collection = Collection.find(collection)
-
end
-
-
19
import_job = ImportJob.last_for user, collection
-
-
# Execution should continue only if the job is in status pending (user may canceled it)
-
19
if import_job.status == 'pending'
-
19
mark_job_as_in_progress(user, collection)
-
19
execute_with_entities(user, collection, columns_spec)
-
end
-
end
-
-
1
def execute_with_entities(user, collection, columns_spec)
-
21
spec_object = ImportWizard::ImportSpecs.new columns_spec, collection
-
-
# Validate new fields
-
21
spec_object.validate_new_columns_do_not_exist_in_collection
-
-
# Read all the CSV to memory
-
19
rows = read_csv_for(user, collection)
-
-
# Put the index of the row in the columns spec
-
19
rows[0].each_with_index do |header, i|
-
81
next if header.blank?
-
81
header = header.strip
-
81
spec_object.annotate_index header, i
-
end
-
-
# Get the id spec
-
19
id_spec = spec_object.id_column
-
-
# Also get the name spec, as the name is mandatory
-
19
name_spec = spec_object.name_column
-
-
19
new_layer = spec_object.create_import_wizard_layer user
-
-
19
begin
-
19
sites = []
-
-
# Now process all rows
-
19
rows[1 .. -1].each do |row|
-
# Check that the name is present
-
45
next unless row[name_spec[:index]].present?
-
-
33
site = nil
-
33
site = collection.sites.find_by_id row[id_spec[:index]] if id_spec && row[id_spec[:index]].present?
-
33
site ||= collection.sites.new properties: {}, collection_id: collection.id, from_import_wizard: true
-
-
33
site.user = user
-
33
sites << site
-
-
# Optimization
-
33
site.collection = collection
-
-
# According to the spec
-
33
spec_object.each_column do |column_spec|
-
106
value = row[column_spec.index].try(:strip)
-
106
column_spec.process row, site
-
end
-
end
-
-
18
Collection.transaction do
-
18
spec_object.new_fields.each_value do |field|
-
15
field.save!
-
end
-
-
# Force computing bounds and such in memory, so a thousand callbacks are not called
-
18
collection.compute_geometry_in_memory
-
-
# Reload collection in order to invalidate cached collection.fields copy and to load the new ones
-
18
collection.fields.reload
-
-
# This will update the existing sites
-
51
sites.each { |site| site.save! unless site.new_record? }
-
-
# And this will create the new ones
-
18
collection.save!
-
-
18
mark_job_as_finished(user, collection)
-
end
-
rescue Exception => ex
-
# Delete layer created by this import process if something unexpectedly fails
-
1
new_layer.destroy if new_layer
-
1
raise ex
-
end
-
-
18
delete_file(user, collection)
-
end
-
-
1
def delete_file(user, collection)
-
46
File.delete(file_for(user, collection))
-
end
-
-
1
def mark_job_as_pending(user, collection)
-
# Move the corresponding ImportJob to status pending, since it'll be enqueued
-
51
(ImportJob.last_for user, collection).pending
-
end
-
-
1
def mark_job_as_canceled_by_user(user, collection)
-
(ImportJob.last_for user, collection).canceled_by_user
-
end
-
-
1
def mark_job_as_in_progress(user, collection)
-
19
(ImportJob.last_for user, collection).in_progress
-
end
-
-
1
def mark_job_as_finished(user, collection)
-
18
(ImportJob.last_for user, collection).finish
-
end
-
-
1
private
-
-
1
def calculate_non_existent_site_id(valid_site_ids, csv_column, resmap_id_column_index)
-
4
invalid_ids = []
-
4
csv_column.each_with_index do |csv_field_value, field_number|
-
6
invalid_ids << field_number unless (csv_field_value.blank? || valid_site_ids.include?(csv_field_value.to_s))
-
end
-
4
[{rows: invalid_ids, column: resmap_id_column_index}] if invalid_ids.length >0
-
end
-
-
1
def validate_column(user, collection, column_spec, fields, csv_column, column_number)
-
42
if column_spec[:use_as].to_sym == :existing_field
-
98
field = fields.detect{|e| e.id.to_s == column_spec[:field_id].to_s}
-
else
-
26
field = Field.new kind: column_spec[:kind].to_s
-
end
-
-
42
validated_csv_column = []
-
42
csv_column.each_with_index do |csv_field_value, field_number|
-
81
begin
-
81
validate_column_value(column_spec, csv_field_value, field, collection)
-
rescue => ex
-
40
description = error_description_for_type(field, column_spec, ex)
-
40
validated_csv_column << {description: description, row: field_number}
-
end
-
end
-
-
82
validated_columns_grouped = validated_csv_column.group_by{|e| e[:description]}
-
42
validated_columns_grouped.map do |description, hash|
-
68
{description: description, column: column_number, rows: hash.map { |e| e[:row] }, type: field.value_type_description, example: field.value_hint }
-
end
-
end
-
-
1
def error_description_for_type(field, column_spec, ex)
-
40
column_index = column_spec[:index]
-
40
"Some of the values in column #{column_index + 1} #{field.error_description_for_invalid_values(ex)}."
-
end
-
-
1
def calculate_duplicated(selection_block, groping_field)
-
112
spec_to_validate = selection_block.call()
-
198
spec_by_field = spec_to_validate.group_by{ |s| s[groping_field]}
-
112
duplicated_columns = {}
-
112
spec_by_field.each do |column_spec|
-
71
if column_spec[1].length > 1
-
45
duplicated_columns[column_spec[0]] = column_spec[1].map{|spec| spec[:index] }
-
end
-
end
-
112
duplicated_columns
-
end
-
-
1
def calculate_reserved_code(selection_block)
-
28
spec_to_validate = selection_block.call()
-
28
invalid_columns = {}
-
28
spec_to_validate.each do |column_spec|
-
27
if Field.reserved_codes().include?(column_spec[:code])
-
5
if invalid_columns[column_spec[:code]]
-
invalid_columns[column_spec[:code]] << column_spec[:index]
-
else
-
5
invalid_columns[column_spec[:code]] = [column_spec[:index]]
-
end
-
end
-
end
-
28
invalid_columns
-
end
-
-
1
def calculate_missing(selection_block, missing_value)
-
56
spec_to_validate = selection_block.call()
-
56
missing_value_columns = []
-
56
spec_to_validate.each do |column_spec|
-
54
if column_spec[missing_value].blank?
-
12
if missing_value_columns.length >0
-
6
missing_value_columns << column_spec[:index]
-
else
-
6
missing_value_columns = [column_spec[:index]]
-
end
-
end
-
end
-
56
{:columns => missing_value_columns} if missing_value_columns.length >0
-
end
-
-
1
def calculate_existing(columns_spec, collection_fields, grouping_field)
-
182
spec_to_validate = columns_spec.select {|spec| spec[:use_as] == 'new_field'}
-
56
existing_columns = {}
-
56
spec_to_validate.each do |column_spec|
-
#Refactor this
-
34
if grouping_field == 'code'
-
174
found = collection_fields.detect{|f| f.code == column_spec[grouping_field]}
-
elsif grouping_field == 'label'
-
174
found = collection_fields.detect{|f| f.name == column_spec[grouping_field]}
-
end
-
34
if found
-
4
if existing_columns[column_spec[grouping_field]]
-
2
existing_columns[column_spec[grouping_field]] << column_spec[:index]
-
else
-
2
existing_columns[column_spec[grouping_field]] = [column_spec[:index]]
-
end
-
end
-
end
-
56
existing_columns
-
end
-
-
1
def validate_column_value(column_spec, field_value, field, collection)
-
81
if field.new_record?
-
43
validate_format_value(column_spec, field_value, collection)
-
else
-
38
field.apply_format_and_validate(field_value, true, collection)
-
end
-
end
-
-
1
def validate_format_value(column_spec, field_value, collection)
-
# Bypass some field validations
-
43
if column_spec[:kind] == 'hierarchy'
-
raise "Hierarchy fields can only be created via web in the Layers page"
-
elsif column_spec[:kind] == 'select_one' || column_spec[:kind] == 'select_many'
-
# options will be created
-
14
return field_value
-
end
-
-
29
column_header = column_spec[:code]? column_spec[:code] : column_spec[:label]
-
-
29
sample_field = Field.new kind: column_spec[:kind], code: column_header
-
-
# We need the collection to validate site_fields
-
18
sample_field.collection = collection
-
-
18
sample_field.apply_format_and_validate(field_value, true, collection)
-
end
-
-
1
def to_columns(collection, rows, admin)
-
8
fields = collection.fields.index_by &:code
-
8
columns_initial_guess = []
-
8
rows[0].each do |header|
-
38
column_spec = {}
-
38
column_spec[:header] = header ? header.strip : ''
-
38
column_spec[:kind] = :text
-
38
column_spec[:code] = header ? header.downcase.gsub(/\s+/, '') : ''
-
38
column_spec[:label] = header ? header.titleize : ''
-
38
columns_initial_guess << column_spec
-
end
-
-
8
columns_initial_guess.each_with_index do |column, i|
-
38
guess_column_usage(column, fields, rows, i, admin)
-
end
-
end
-
-
1
def guess_column_usage(column, fields, rows, i, admin)
-
38
if (field = fields[column[:header]])
-
22
column[:use_as] = :existing_field
-
22
column[:layer_id] = field.layer_id
-
22
column[:field_id] = field.id
-
22
column[:kind] = field.kind.to_sym
-
22
return
-
end
-
-
16
if column[:header] =~ /^resmap-id$/i
-
1
column[:use_as] = :id
-
1
column[:kind] = :id
-
1
return
-
end
-
-
15
if column[:header] =~ /^name$/i
-
2
column[:use_as] = :name
-
2
column[:kind] = :name
-
2
return
-
end
-
-
13
if column[:header] =~ /^\s*lat/i
-
2
column[:use_as] = :lat
-
2
column[:kind] = :location
-
2
return
-
end
-
-
11
if column[:header] =~ /^\s*(lon|lng)/i
-
2
column[:use_as] = :lng
-
2
column[:kind] = :location
-
2
return
-
end
-
-
9
if column[:header] =~ /last updated/i
-
column[:use_as] = :ignore
-
column[:kind] = :ignore
-
return
-
end
-
-
9
if not admin
-
column[:use_as] = :ignore
-
return
-
end
-
-
9
found = false
-
-
9
rows[1 .. -1].each do |row|
-
11
next if row[i].blank?
-
-
8
found = true
-
-
8
if row[i].start_with?('0')
-
2
column[:use_as] = :new_field
-
2
column[:kind] = :text
-
2
return
-
end
-
-
6
begin
-
6
Float(row[i])
-
rescue
-
2
column[:use_as] = :new_field
-
2
column[:kind] = :text
-
2
return
-
end
-
end
-
-
5
if found
-
3
column[:use_as] = :new_field
-
3
column[:kind] = :numeric
-
else
-
2
column[:use_as] = :ignore
-
end
-
end
-
-
1
def read_csv_for(user, collection)
-
100
csv = CSV.read(file_for(user, collection))
-
-
# Remove empty rows at the end
-
206
while (last = csv.last) && last.empty?
-
6
csv.pop
-
end
-
-
100
csv
-
end
-
-
1
def file_for(user, collection)
-
207
"#{TmpDir}/#{user.id}_#{collection.id}.csv"
-
end
-
end
-
end
-
1
class ImportWizard::BaseFieldSpecs
-
1
def initialize(column_spec)
-
106
@column_spec = column_spec
-
end
-
-
1
def index
-
106
@column_spec[:index]
-
end
-
end
-
1
class ImportWizard::ExistingFieldSpecs < ImportWizard::BaseFieldSpecs
-
1
def initialize(existing_fields, column_spec)
-
33
super(column_spec)
-
33
@existing_fields = existing_fields
-
end
-
-
1
def process(row, site)
-
33
value = row[@column_spec[:index]]
-
33
existing_field = @existing_fields[@column_spec[:field_id].to_i]
-
-
33
if existing_field
-
33
case existing_field.kind
-
when 'select_one'
-
-
4
site.properties_will_change!
-
4
site.properties[existing_field.es_code] = existing_field.apply_format_and_validate value, true, site.collection
-
when 'select_many'
-
4
site.properties[existing_field.es_code] = []
-
4
if value
-
4
value.split(',').each do |v|
-
5
option = v.strip
-
5
option = existing_field.apply_format_and_validate(option, true, site.collection, site).first
-
-
5
site.properties_will_change!
-
5
site.properties[existing_field.es_code] << option
-
end
-
end
-
else
-
25
site.properties_will_change!
-
25
site.properties[existing_field.es_code] = existing_field.apply_format_and_validate value, true, site.collection, site
-
end
-
end
-
end
-
end
-
1
class ImportWizard::ImportSpecs
-
1
def initialize(columns_spec_array, collection)
-
21
@collection = collection
-
21
@existing_fields = collection.fields.index_by &:id
-
-
21
@data = columns_spec_array.map! &:with_indifferent_access
-
21
relate_codes_and_labels_for_select_fields
-
end
-
-
1
def new_fields
-
18
@new_fields
-
end
-
-
1
def validate_new_columns_do_not_exist_in_collection
-
21
collection_fields = @collection.fields(:include => :layer)
-
21
@data.each do |col_spec|
-
77
if col_spec[:use_as] == 'new_field'
-
# Validate code
-
183
found = collection_fields.detect{|f| f.code == col_spec[:code]}
-
19
if found
-
1
raise "Can't save field from column #{col_spec[:header]}: A field with code '#{col_spec[:code]}' already exists in the layer named #{found.layer.name}"
-
end
-
# Validate name
-
181
found = collection_fields.detect{|f| f.name == col_spec[:label]}
-
18
if found
-
1
raise "Can't save field from column #{col_spec[:header]}: A field with label '#{col_spec[:label]}' already exists in the layer named #{found.layer.name}"
-
end
-
end
-
end
-
end
-
-
1
def annotate_index(header, index)
-
432
spec = @data.find{|x| x[:header].strip == header}
-
81
spec[:index] = index if spec
-
end
-
-
1
def id_column
-
54
@data.find{|x| x[:use_as].to_s == 'id'}
-
end
-
-
1
def name_column
-
44
@data.find{|x| x[:use_as].to_s == 'name'}
-
end
-
-
1
def create_import_wizard_layer(user)
-
# Prepare the new layer
-
19
layer = Layer.new name: 'Import wizard', ord: @collection.next_layer_ord
-
19
layer.user = user
-
19
layer.collection = @collection
-
-
# Prepare the fields: we index by code, so later we can reference them faster
-
19
@new_fields = {}
-
-
# Fill the fields with the column specs.
-
# We completely ignore the ones with selectKind equal to 'label', as processing those with
-
# 'code' and 'both' is enough
-
19
spec_i = 1
-
19
@data.each do |spec|
-
75
if spec[:use_as] == 'new_field'
-
17
if spec[:selectKind] != 'label'
-
# Set field to code if there's no label defined
-
16
new_field_name = spec[:label].present? ? spec[:label] : spec[:code]
-
-
16
@new_fields[spec[:code]] = layer.fields.new code: spec[:code], name: new_field_name, kind: spec[:kind], ord: spec_i
-
16
@new_fields[spec[:code]].layer = layer
-
16
spec_i += 1
-
end
-
end
-
end
-
-
# No need to create a layer if there are no new fields
-
19
return nil unless spec_i > 1
-
-
7
layer.save!
-
7
layer
-
end
-
-
1
def each_column
-
33
@data.each do |column|
-
113
case column[:use_as]
-
when 'new_field'
-
24
yield ImportWizard::NewFieldSpecs.new(@new_fields, column)
-
when 'existing_field'
-
33
yield ImportWizard::ExistingFieldSpecs.new(@existing_fields, column)
-
when 'name'
-
33
yield ImportWizard::NameFieldSpecs.new(column)
-
when 'lat'
-
8
yield ImportWizard::LatFieldSpecs.new(column)
-
when 'lng'
-
8
yield ImportWizard::LngFieldSpecs.new(column)
-
end
-
end
-
end
-
-
1
private
-
-
1
def relate_codes_and_labels_for_select_fields
-
# Relate code and label select kinds for 'select one' and 'select many'
-
21
@data.each do |spec|
-
77
if spec[:use_as] == 'new_field' && (spec[:kind] == 'select_one' || spec[:kind] == 'select_many') && spec[:selectKind] == 'code'
-
3
spec[:related] = @data.find{|x| x[:code] == spec[:code] && x[:selectKind] == 'label'}
-
end
-
end
-
end
-
end
-
1
class ImportWizard::LatFieldSpecs < ImportWizard::BaseFieldSpecs
-
1
def process(row, site)
-
8
site.lat = row[@column_spec[:index]]
-
end
-
end
-
1
class ImportWizard::LngFieldSpecs < ImportWizard::BaseFieldSpecs
-
1
def process(row, site)
-
8
site.lng = row[@column_spec[:index]]
-
end
-
end
-
1
class ImportWizard::NameFieldSpecs < ImportWizard::BaseFieldSpecs
-
1
def process(row, site)
-
33
site.name = row[@column_spec[:index]]
-
end
-
end
-
1
class ImportWizard::NewFieldSpecs < ImportWizard::BaseFieldSpecs
-
1
def initialize(new_fields, column_spec)
-
24
super(column_spec)
-
24
@new_fields = new_fields
-
end
-
-
1
def process(row, site)
-
24
value = row[@column_spec[:index]]
-
-
# New hierarchy fields cannot be created via import wizard
-
24
raise "Hierarchy fields can only be created via web in the Layers page" if @column_spec[:kind] == 'hierarchy'
-
-
# For select one and many we need to collect the fields options
-
24
if @column_spec[:kind] == 'select_one' || @column_spec[:kind] == 'select_many'
-
# For select_one fields each value will be only one option
-
# and for select_many fields we may create more than one option per value
-
11
options_to_be_created = if @column_spec[:kind] == 'select_many'
-
3
value.split(',').map{|v| v.strip}
-
else
-
10
[value]
-
end
-
-
11
options_to_be_created.each do |option|
-
12
field = @new_fields[@column_spec[:code]]
-
12
field.config ||= {'options' => [], 'next_id' => 1}
-
-
12
code = nil
-
12
label = nil
-
-
# Compute code and label based on the selectKind
-
12
case @column_spec[:selectKind]
-
when 'code'
-
3
next unless @column_spec[:related]
-
-
3
code = option
-
-
3
label = row[@column_spec[:related][:index]]
-
when 'label'
-
# Processing just the code is enough
-
3
return
-
when 'both'
-
6
code = option
-
6
label = option
-
end
-
-
# Add to options, if not already present
-
9
if code.present? && !label.nil?
-
16
existing = field.config['options'].find{|x| x['code'] == code}
-
9
if !existing
-
7
field.config['options'] << {'id' => field.config['next_id'], 'code' => code, 'label' => label}
-
7
field.config['next_id'] += 1
-
end
-
end
-
end
-
end
-
-
21
field = @new_fields[@column_spec[:code]]
-
21
site.properties_will_change!
-
-
# We need the collection to validate site_fields
-
21
field.collection = field.layer.collection
-
-
21
site.properties[field.es_code] = field.apply_format_and_validate value, true, field.layer.collection, site
-
end
-
end
-
1
class Language < ActiveRecord::Base
-
end
-
1
class Layer < ActiveRecord::Base
-
1
include Activity::AwareConcern
-
1
include HistoryConcern
-
-
1
belongs_to :collection
-
2364
has_many :fields, -> { order('ord')}, dependent: :destroy
-
8
has_many :field_histories, -> { order('ord')}, dependent: :destroy
-
-
1
accepts_nested_attributes_for :fields, :allow_destroy => true
-
-
1
validates_presence_of :ord
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
# I'd move this code to a concern, but it works differntly (the fields don't
-
# have an id). Must probably be a bug in Active Record.
-
1
after_create :create_created_activity, :unless => :mute_activities
-
1
def create_created_activity
-
475
fields_data = fields.map do |field|
-
84
hash = {'id' => field.id, 'kind' => field.kind, 'code' => field.code, 'name' => field.name}
-
84
hash['config'] = field.config if field.config
-
84
hash
-
end
-
475
Activity.create! item_type: 'layer', action: 'created', collection_id: collection.id, layer_id: id, user_id: user.id, 'data' => {'name' => name, 'fields' => fields_data}
-
end
-
-
1
before_update :record_status_before_update, :unless => :mute_activities
-
1
def record_status_before_update
-
10
@name_was = name_was
-
10
@before_update_fields = Field.where("layer_id = ?", id)
-
10
@before_update_fields.reload()
-
10
@before_update_changes = changes.dup
-
end
-
-
1
after_update :create_updated_activity, :unless => :mute_activities
-
1
def create_updated_activity
-
10
layer_changes = changes.except('updated_at').to_hash
-
-
10
after_update_fields = fields.reload
-
-
10
added = []
-
10
changed = []
-
10
deleted = []
-
-
10
after_update_fields.each do |new_field|
-
14
old_field = @before_update_fields.find { |f| f.id == new_field.id }
-
7
if old_field
-
6
hash = field_hash(new_field)
-
6
really_changed = false
-
-
6
['name', 'code', 'kind', 'config'].each do |key|
-
24
if old_field[key] != new_field[key]
-
3
really_changed = true
-
3
hash[key] = [old_field[key], new_field[key]]
-
end
-
end
-
-
6
changed.push hash if really_changed
-
else
-
1
added.push field_hash(new_field)
-
end
-
end
-
-
10
@before_update_fields.each do |old_field|
-
15
new_field = after_update_fields.find { |f| f.id == old_field.id }
-
8
deleted.push field_hash(old_field) unless new_field
-
end
-
-
10
layer_changes['added'] = added if added.present?
-
10
layer_changes['changed'] = changed if changed.present?
-
10
layer_changes['deleted'] = deleted if deleted.present?
-
-
10
Activity.create! item_type: 'layer', action: 'changed', collection_id: collection.id, layer_id: id, user_id: user.id, 'data' => {'name' => @name_was || name, 'changes' => layer_changes}
-
end
-
-
1
after_destroy :create_deleted_activity, :unless => :mute_activities, :if => :user
-
1
def create_deleted_activity
-
4
Activity.create! item_type: 'layer', action: 'deleted', collection_id: collection.id, layer_id: id, user_id: user.id, 'data' => {'name' => name}
-
end
-
-
1
def history_concern_foreign_key
-
485
self.class.name.foreign_key
-
end
-
-
# Returns the next ord value for a field that is going to be created
-
1
def next_field_ord
-
1753
field = fields.pluck('max(ord) as o').first
-
1753
field ? field.to_i + 1 : 1
-
end
-
-
1
def get_associated_threshold_ids
-
-
layerFieldIDs = self.fields.map { |field| field.id}
-
associated_threshold_ids = []
-
-
self.collection.thresholds.map { |threshold|
-
-
thresholdFieldIDs = threshold.conditions.map { |condition| condition['field'].to_i}
-
-
if (layerFieldIDs - thresholdFieldIDs).length < layerFieldIDs.length
-
associated_threshold_ids.push(threshold.id)
-
end
-
-
}
-
-
associated_threshold_ids
-
-
end
-
-
1
def decode_raw_layer layer
-
data = layer.except('fields')
-
data['fields_attributes'] = {}
-
layer['fields'].each_with_index do |field,index|
-
data['fields_attributes'][index] = field.except('id')
-
data['fields_attributes'][index]['collection_id'] = collection_id
-
end
-
data
-
end
-
-
1
private
-
-
1
def field_hash(field)
-
9
field_hash = {'id' => field.id, 'code' => field.code, 'name' => field.name, 'kind' => field.kind}
-
9
field_hash['config'] = field.config if field.config.present?
-
9
field_hash
-
end
-
-
end
-
1
class LayerHistory < ActiveRecord::Base
-
1
belongs_to :layer
-
1
belongs_to :collection
-
-
1
has_many :field_histories, foreign_key: "layer_id", primary_key: "layer_id"
-
-
1
def as_json(options = {})
-
{collection_id: collection_id, id: layer_id, name: name, ord: ord, public: public, fields: field_histories.map {|f| f.as_json} }
-
end
-
-
end
-
1
class LayerMembership < ActiveRecord::Base
-
1
belongs_to :collection
-
1
belongs_to :user
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
1
after_save :touch_user_lifespan
-
1
after_destroy :touch_user_lifespan
-
-
1
def self.filter_layer_membership current_user , collection_id
-
builder = LayerMembership.where(
-
:collection_id => collection_id, :user_id => current_user.id)
-
end
-
end
-
1
class MapSearch
-
1
include SearchBase
-
-
1
def initialize(collection_ids, options = {})
-
16
@collection_ids = Array(collection_ids)
-
16
@index_names = Collection.index_names_with_options(*@collection_ids, options)
-
# @search.size 100000
-
16
@bounds = {s: -90, n: 90, w: -180, e: 180}
-
16
@hierarchy = {}
-
end
-
-
1
def zoom=(zoom)
-
16
@zoom = zoom
-
end
-
-
1
def bounds=(bounds)
-
3
@bounds = bounds
-
3
adjust_bounds_to_world_limits
-
end
-
-
1
def exclude_id(id)
-
1
@exclude_id = id
-
end
-
-
1
def selected_hierarchy(hierarchy_code, selected_hierarchy)
-
@hierarchy[:code] = hierarchy_code
-
@hierarchy[:selected] = selected_hierarchy
-
end
-
-
1
def results
-
17
return {} if @collection_ids.empty?
-
-
16
listener = clusterer = Clusterer.new(@zoom)
-
16
clusterer.highlight @hierarchy if @hierarchy
-
16
listener = ElasticSearch::SitesAdapter::SkipIdListener.new(listener, @exclude_id) if @exclude_id
-
-
16
set_bounds_filter
-
-
16
adapter = ElasticSearch::SitesAdapter.new listener
-
16
adapter.return_property @hierarchy[:code] if @hierarchy[:code]
-
-
16
adapter.parse stream
-
-
16
clusterer.clusters
-
end
-
-
1
def sites_json
-
return {} if @collection_ids.empty?
-
sites = []
-
data = JSON.parse(stream.read)
-
data["hits"]["hits"].each do |item|
-
site = Hash.new
-
site[:collection_id] = item['_index'].split('_')[1]
-
item['_source'].each do |key, value|
-
site[key] = value
-
end
-
sites.push site
-
end
-
sites
-
end
-
-
1
private
-
-
1
def set_bounds_filter
-
16
if @zoom
-
16
width, height = Clusterer.cell_size_for @zoom
-
16
extend_to_cell_limits width, height
-
16
adjust_bounds_to_world_limits
-
end
-
-
16
add_filter exists: {field: :location}
-
16
add_filter geo_bounding_box: {
-
location: {
-
top_left: {
-
lat: @bounds[:n],
-
lon: @bounds[:w]
-
},
-
bottom_right: {
-
lat: @bounds[:s],
-
lon: @bounds[:e]
-
},
-
}
-
}
-
end
-
-
1
def extend_to_cell_limits(width, height)
-
16
extend_to_limit :n, 1, height
-
16
extend_to_limit :s, -1, height
-
16
extend_to_limit :e, 1, width
-
16
extend_to_limit :w, -1, width
-
end
-
-
1
def extend_to_limit(key, sign, size)
-
64
value = @bounds[key].to_f / size
-
64
@bounds[key] = (sign >= 0 ? value.ceil : value.floor) * size
-
end
-
-
1
def adjust_bounds_to_world_limits
-
#See https://github.com/elasticsearch/elasticsearch/pull/1602#issuecomment-5978326
-
19
@bounds[:n] = 89.99 if @bounds[:n].to_f > 90
-
19
@bounds[:s] = -89.99 if @bounds[:s].to_f < -90
-
19
@bounds[:e] = 179.99 if @bounds[:e].to_f > 180
-
19
@bounds[:w] = -179.99 if @bounds[:w].to_f < -180
-
end
-
-
1
def collection
-
16
@collection ||= Collection.find @collection_ids[0]
-
end
-
-
1
def stream
-
16
client = Elasticsearch::Client.new
-
16
info = client.transport.hosts.first
-
16
protocol, host, port = info[:protocol], info[:host], info[:port]
-
-
16
url = "#{protocol}://#{host}:#{port}/#{@index_names}/site/_search"
-
16
body = get_body
-
16
body[:size] = 100_00
-
-
16
if Rails.logger.level <= Logger::DEBUG
-
16
Rails.logger.debug to_curl(client, body)
-
end
-
-
16
uri = URI(url)
-
16
reader, writer = IO.pipe
-
16
producer = Thread.new(writer) do |io|
-
16
begin
-
16
Net::HTTP.start(uri.host, uri.port) do |http|
-
16
request = Net::HTTP::Get.new uri.request_uri
-
16
http.request request, body.to_json do |response|
-
32
response.read_body { |segment| io.write segment.dup.force_encoding("UTF-8") }
-
end
-
end
-
rescue Exception => ex
-
Rails.logger.error ex.message + "\n" + ex.backtrace.join("\n")
-
ensure
-
16
io.close
-
end
-
end
-
16
reader
-
end
-
end
-
1
require 'base64'
-
-
1
class MarshalZipSerializable
-
1
def self.dump(x)
-
3706
return nil if x.nil?
-
-
2335
Zlib.deflate(Marshal.dump(x), 9)
-
end
-
-
1
def self.load(x)
-
3682
return nil if x.nil?
-
-
435
Marshal.load(Zlib.inflate(x))
-
end
-
end
-
1
class Membership < ActiveRecord::Base
-
1
include Membership::ActivityConcern
-
1
include Membership::LayerAccessConcern
-
1
include Membership::SitesPermissionConcern
-
-
1
belongs_to :user
-
1
belongs_to :collection
-
1
has_one :none_sites_permission, dependent: :destroy
-
1
has_one :read_sites_permission, dependent: :destroy
-
1
has_one :write_sites_permission, dependent: :destroy
-
-
1
before_destroy :destroy_collection_memberships
-
-
1
validates :user_id, :uniqueness => { scope: :collection_id, message: "membership already exists" }
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
1
after_save :touch_user_lifespan
-
1
after_destroy :touch_user_lifespan
-
-
1
def destroy_collection_memberships
-
1
collection.layer_memberships.where(:user_id => user_id).destroy_all
-
end
-
-
1
def set_layer_access(options = {})
-
14
intent = options[:verb].to_s
-
-
14
read = nil
-
14
write = nil
-
-
14
if intent == 'read'
-
9
read = options[:access]
-
# If the intent is to set read permissions, we assume write permissions have to be denied.
-
9
write = false
-
elsif intent == 'write'
-
5
write = options[:access]
-
# Write permissions imply read permissions.
-
5
read = true if write
-
end
-
-
14
lm = collection.layer_memberships.where(:layer_id => options[:layer_id], :user_id => user_id).first
-
14
lm.destroy if lm
-
14
if options[:access] == "true" || options[:access] == true
-
10
collection.layer_memberships.create! :layer_id => options[:layer_id], :user_id => user_id, :read => read, :write => write
-
end
-
-
end
-
-
#TODO: refactor Name, Location, Site, and Layer permission into membership subclases
-
1
def can_read?(object)
-
if admin
-
true
-
elsif object == "name"
-
name_permission.can_read?
-
elsif object == "location"
-
location_permission.can_read?
-
else
-
raise "Undefined element #{object} for membership."
-
end
-
end
-
-
#TODO: refactor Name, Location, Site, and Layer permission into membership subclases
-
1
def can_update?(object)
-
if admin
-
true
-
elsif object == "name"
-
name_permission.can_update?
-
elsif object == "location"
-
location_permission.can_update?
-
else
-
raise "Undefined element #{object} for membership."
-
end
-
end
-
end
-
1
module Membership::ActivityConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_create :create_activity_if_first_user
-
end
-
-
1
def create_activity_if_first_user
-
586
memberships = collection.memberships
-
586
if memberships.length == 1
-
500
Activity.create! item_type: 'collection', action: 'created', collection_id: collection.id, user_id: memberships[0].user_id, 'data' => {'name' => collection.name}
-
end
-
end
-
end
-
1
module Membership::LayerAccessConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
before_destroy :destroy_collection_memberships
-
end
-
-
1
def set_layer_access(options = {})
-
read = options[:verb].to_s == 'read' ? options[:access] : nil
-
write = options[:verb].to_s == 'write' ? options[:access] : nil
-
-
lm = collection.layer_memberships.where(:layer_id => options[:layer_id], :user_id => user_id).first
-
if lm
-
lm.read = read unless read.nil?
-
lm.write = write unless write.nil?
-
if lm.read || lm.write
-
lm.save!
-
else
-
lm.destroy
-
end
-
else
-
collection.layer_memberships.create! :layer_id => options[:layer_id], :user_id => user_id, :read => read, :write => write
-
end
-
end
-
-
1
def destroy_collection_memberships
-
collection.layer_memberships.where(:user_id => user_id).destroy_all
-
end
-
end
-
1
module Membership::SitesPermissionConcern
-
1
extend ActiveSupport::Concern
-
-
1
def update_sites_permission(sites_permission = {})
-
5
sites_permission.each do |type, permission|
-
7
if permission[:some_sites].is_a? Hash
-
1
permission[:some_sites] = permission[:some_sites].values
-
elsif not permission[:some_sites]
-
3
permission[:some_sites] = []
-
end
-
-
7
self.find_or_build_sites_permission(type).update_attributes permission
-
end
-
end
-
-
1
def find_or_build_sites_permission(type)
-
9
send "#{type.to_s}_sites_permission" or send "build_#{type.to_s}_sites_permission"
-
end
-
-
1
def sites_permission
-
7
permission = { none: none_sites_permission, read: read_sites_permission, write: write_sites_permission }
-
7
permission = { none: build_none_sites_permission, read: build_read_sites_permission, write: build_write_sites_permission } if admin
-
7
permission
-
end
-
end
-
1
class Message < ActiveRecord::Base
-
1
validates_presence_of :body, :from
-
1
validates_presence_of :guid, :unless => :is_send
-
1
INVALID_COMMAND = "Invalid command"
-
1
belongs_to :collection
-
1
after_create :update_message_quota
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
def process!(context=nil)
-
5
self.reply = visit(parse.command, context)
-
end
-
-
1
def parse
-
5
CommandParser.new.parse(self.body) or raise INVALID_COMMAND
-
end
-
-
1
def visit(command, context)
-
4
command.sender = self.sender
-
4
command.accept ExecVisitor.new(context)
-
end
-
-
1
def sender
-
6
if channel?(:sms)
-
5
User.find_by_phone_number(self.from[6..-1]) || User.find_by_phone_number("+" + self.from[6..-1])
-
end
-
end
-
-
1
def channel?(protocol)
-
8
self.from && self.from.start_with?("#{protocol.to_s}://")
-
end
-
-
1
def self.getCollectionId(bodyMsg, start)
-
3
k = 1
-
3
for j in (1..bodyMsg.length)
-
9
if (bodyMsg[start+k] != " ")
-
6
k = k+1
-
else
-
3
return bodyMsg[start..start+(k-1)]
-
break
-
end
-
end
-
end
-
-
1
def self.log nuntium_messages, collection_id
-
2
nuntium_messages.each do |ns|
-
2
message = Message.new from: ns[:from], to: ns[:to], body: ns[:body], channel: ns[:suggested_channel], is_send: true, collection_id: collection_id
-
2
message.save!
-
end
-
#c = Collection.find collection_id
-
#c.quota = c.quota - nuntium_messages.length
-
#c.save!
-
end
-
-
1
def update_message_quota
-
13
return unless is_send
-
2
c = Collection.find collection_id
-
2
c.quota = c.quota - 1
-
2
c.save!
-
end
-
end
-
1
class NoneSitesPermission < SitesPermission; end
-
1
class Plugin
-
1
include Singleton
-
-
1
class << self
-
1
def inherited(plugin)
-
4
super
-
4
all << plugin.instance
-
end
-
-
1
def all
-
2133
@plugins ||= []
-
end
-
-
1
def find_by_names(*plugins)
-
all.select { |plugin| plugins.include? plugin.name }
-
end
-
-
1
def hooks(name)
-
all.map do |plugin|
-
8500
plugin.hooks[name]
-
2125
end.flatten
-
end
-
-
1
def method_missing(method_name, *args, &block)
-
18
if block_given?
-
4
instance.hooks[method_name] << block
-
else
-
14
instance.hooks[method_name] << args.first
-
end
-
end
-
end
-
-
1
def name
-
8
self.class.parent_name.underscore
-
end
-
-
1
def hooks
-
8557
@hooks ||= Hash.new { |h, k| h[k] = [] }
-
end
-
-
# FIXME: not being used
-
1
def call_hook name, *args
-
@hooks[name].each do |proc|
-
proc.call *args
-
end
-
end
-
end
-
1
class Prefix < ActiveRecord::Base
-
1
validates_presence_of :version
-
1
validates_uniqueness_of :version
-
-
1
START = 'AA'
-
-
1
def self.next
-
304
prefix = START
-
304
if last_prefix = Prefix.last
-
6
prefix = last_prefix.version.next.gsub("O", "P")
-
end
-
304
Prefix.create :version => prefix
-
end
-
-
end
-
1
class ReadSitesPermission < SitesPermission; end
-
1
class Search
-
1
include SearchBase
-
-
1
class Results
-
1
include Enumerable
-
-
1
attr_reader :sites
-
1
attr_reader :page
-
1
attr_reader :previous_page
-
1
attr_reader :next_page
-
1
attr_reader :total_pages
-
1
attr_reader :total_count
-
-
1
def initialize(options)
-
107
@sites = options[:sites]
-
107
@page = options[:page]
-
107
@previous_page = options[:previous_page]
-
107
@next_page = options[:next_page]
-
107
@total_pages = options[:total_pages]
-
107
@total_count = options[:total_count]
-
end
-
-
1
def total
-
4
total_count
-
end
-
-
1
def each(&block)
-
120
@sites.each(&block)
-
end
-
-
1
def [](index)
-
10
@sites[index]
-
end
-
-
1
def empty?
-
@sites.empty?
-
end
-
-
1
def length
-
2
@sites.length
-
end
-
end
-
-
1
attr_accessor :page_size
-
1
attr_accessor :collection
-
-
1
def initialize(collection, options)
-
119
@collection = collection
-
119
@index_names = collection.index_names_with_options(options)
-
119
@snapshot_id = options[:snapshot_id]
-
119
if options[:current_user]
-
21
@current_user = options[:current_user]
-
else
-
98
@current_user = User.find options[:current_user_id] if options[:current_user_id]
-
end
-
119
@from = 0
-
119
@page_size = 50
-
end
-
-
1
def page(page)
-
1
@page = page
-
1
self
-
end
-
-
1
def offset(offset)
-
@offset = offset
-
self
-
end
-
-
1
def limit(limit)
-
@limit = limit
-
self
-
end
-
-
1
def sort(es_code, ascendent = true)
-
6
case es_code
-
when 'id', 'name.downcase'
-
sort = es_code
-
when 'name'
-
3
sort = 'name.downcase'
-
else
-
3
es_code = remove_at_from_code es_code
-
6
field = fields.find { |x| x.code == es_code || x.es_code == es_code }
-
3
if field && field.kind == 'text'
-
sort = "#{field.es_code}.downcase"
-
else
-
3
sort = decode(es_code)
-
end
-
end
-
6
ascendent = ascendent ? 'asc' : 'desc'
-
-
6
@sorts ||= []
-
6
@sorts.push sort => ascendent
-
-
6
self
-
end
-
-
1
def sort_multiple(sort_list)
-
1
sort_list.each_pair do |es_code, ascendent|
-
2
sort(es_code, ascendent)
-
end
-
1
self
-
end
-
-
1
def unlimited
-
17
@unlimited = true
-
17
self
-
end
-
-
1
def get_body
-
110
body = super
-
-
110
if @sorts
-
5
body[:sort] = @sorts
-
else
-
105
body[:sort] = 'name.downcase'
-
end
-
-
110
if @select_fields
-
2
body[:fields] = @select_fields
-
end
-
-
110
if @page
-
1
body[:from] = (@page - 1) * page_size
-
end
-
-
110
if @offset && @limit
-
body[:from] = @offset
-
body[:size] = @limit
-
elsif @unlimited
-
10
body[:size] = 1_000_0
-
else
-
100
body[:size] = page_size
-
end
-
-
110
body
-
end
-
-
1
def results
-
-
110
body = get_body
-
-
110
client = Elasticsearch::Client.new
-
-
110
if Rails.logger.level <= Logger::DEBUG
-
110
Rails.logger.debug to_curl(client, body)
-
end
-
-
110
results = client.search index: @index_names, type: 'site', body: body
-
-
107
hits = results["hits"]
-
107
sites = hits["hits"]
-
107
total_count = hits["total"]
-
-
# When selecting fields, the results are returned in an array.
-
# We only keep the first element of that array.
-
107
if @select_fields
-
2
sites.each do |site|
-
3
fields = site["fields"]
-
3
if fields
-
3
fields.each do |key, value|
-
6
fields[key] = value.first if value.is_a?(Array)
-
end
-
end
-
end
-
end
-
-
107
results = {sites: sites, total_count: total_count}
-
107
if @page
-
1
results[:page] = @page
-
1
results[:previous_page] = @page - 1 if @page > 1
-
1
results[:total_pages] = (total_count.to_f / page_size).ceil
-
1
if @page < results[:total_pages]
-
results[:next_page] = @page + 1
-
end
-
end
-
107
Results.new(results)
-
end
-
-
# Returns the results from ElasticSearch but with codes as keys and codes as
-
# values (when applicable).
-
1
def api_results
-
23
visible_fields = @collection.visible_fields_for(@current_user, snapshot_id: @snapshot_id)
-
199
visible_fields.each { |field| field.cache_for_read }
-
-
23
fields_by_es_code = visible_fields.index_by &:es_code
-
-
23
results = results()
-
23
results.each do |item|
-
24
properties = item['_source']['properties']
-
24
item['_source']['identifiers'] = []
-
24
item['_source']['properties'] = {}
-
-
24
properties.each_pair do |es_code, value|
-
100
field = fields_by_es_code[es_code]
-
100
if field
-
100
item['_source']['properties'][field.code] = field.api_value(value)
-
end
-
end
-
end
-
23
results
-
end
-
-
# Returns the results from ElasticSearch but with the location field
-
# returned as lat/lng fields, and the date as a date object
-
1
def ui_results
-
4
fields_by_es_code = @collection.visible_fields_for(@current_user, snapshot_id: @snapshot_id).index_by &:es_code
-
-
4
results = results()
-
4
results.each do |item|
-
3
if item['_source']['location']
-
3
item['_source']['lat'] = item['_source']['location']['lat']
-
3
item['_source']['lng'] = item['_source']['location']['lon']
-
3
item['_source'].delete 'location'
-
end
-
3
item['_source']['created_at'] = Site.parse_time item['_source']['created_at']
-
3
item['_source']['updated_at'] = Site.parse_time item['_source']['updated_at']
-
3
item['_source']['properties'] = item['_source']['properties'].select { |es_code, value|
-
12
fields_by_es_code[es_code]
-
}
-
end
-
4
results
-
end
-
-
1
def histogram_results(field_es_code)
-
body = get_body
-
-
client = Elasticsearch::Client.new
-
results = client.search index: @index_names, type: 'site', body: body
-
-
histogram = {}
-
results["facets"]["field_#{field_es_code}_ratings"]["terms"].each do |item|
-
histogram[item["term"]] = item["count"] unless item["count"] == 0
-
end
-
histogram
-
end
-
end
-
1
module SearchBase
-
1
def use_codes_instead_of_es_codes
-
42
@use_codes_instead_of_es_codes = true
-
42
self
-
end
-
-
1
def id(id)
-
4
if id.is_a?(Array)
-
add_filter terms: {id: id}
-
else
-
4
add_filter term: {id: id}
-
end
-
4
self
-
end
-
-
1
def hierarchy_mode(childs_ids)
-
childs_ids = [] if childs_ids == nil
-
add_filter term: {"id" => childs_ids}
-
end
-
-
1
def name_start_with(name)
-
add_filter prefix: {name: name.downcase}
-
end
-
-
1
def name(name)
-
add_filter term: {"name.downcase" => name.downcase}
-
end
-
-
1
def name_search(name)
-
add_query prefix: {name: name.downcase}
-
end
-
-
1
def uuid(uuid)
-
add_filter term: {uuid: uuid}
-
end
-
-
1
def eq(field, value)
-
35
if value.blank?
-
add_filter missing: {field: field.es_code}
-
return self
-
end
-
-
35
query_params = query_params(field, value)
-
30
add_filter query_params
-
-
30
self
-
end
-
-
1
def not_eq(field, value)
-
query_params = query_params(field, value)
-
add_filter not: query_params
-
self
-
end
-
-
1
def query_params(field, value)
-
35
query_key = field.es_code
-
35
validated_value = field.parse_for_query(value, @use_codes_instead_of_es_codes)
-
-
30
if field.kind == 'date'
-
4
date_field_range(query_key, validated_value)
-
26
elsif field.kind == 'yes_no' && !validated_value.is_a?(Array) && !Field.yes?(value)
-
1
{ not: { :term => { query_key => true }}} # so we return false & nil values
-
25
elsif validated_value.is_a? Array
-
2
{ terms: {query_key => validated_value} }
-
else
-
23
{ term: {query_key => validated_value} }
-
end
-
-
# elsif field.select_kind?
-
# {term: {query_key => validated_value}}
-
# add_filter term: {query_key => validated_value}
-
# else
-
# end
-
-
end
-
-
1
def date_field_range(key, valid_value)
-
4
date_from = valid_value[:date_from]
-
4
date_to = valid_value[:date_to]
-
-
4
{ range: { key => { gte: date_from, lte: date_to } } }
-
end
-
-
1
def under(field, value)
-
4
if value.blank?
-
add_filter missing: {field: field.es_code}
-
return self
-
end
-
4
if field.find_hierarchy_by_id value
-
2
value = field.descendants_of_in_hierarchy value, false
-
elsif field.find_hierarchy_by_name value
-
2
value = field.descendants_of_in_hierarchy value, true
-
else
-
raise field.invalid_field_message()
-
end
-
4
query_key = field.es_code
-
4
add_filter terms: {query_key => value}
-
4
self
-
end
-
-
1
def starts_with(field, value)
-
4
validated_value = field.apply_format_query_validation(value, @use_codes_instead_of_es_codes)
-
4
query_key = field.es_code
-
4
add_prefix key: query_key, value: validated_value
-
4
self
-
end
-
-
1
['lt', 'lte', 'gt', 'gte'].each do |op|
-
4
class_eval %Q(
-
def #{op}(field, value)
-
validated_value = field.apply_format_query_validation(value, @use_codes_instead_of_es_codes)
-
add_filter range: {field.es_code => {#{op}: validated_value}}
-
self
-
end
-
)
-
end
-
-
1
def op(field, op, value)
-
6
case op.to_s.downcase
-
1
when '<', 'l' then lt(field, value)
-
when '<=', 'lte' then lte(field, value)
-
when '>', 'gt' then gt(field, value)
-
1
when '>=', 'gte' then gte(field, value)
-
when '=', '==', 'eq' then eq(field, value)
-
when '!=' then not_eq(field, value)
-
4
when 'under' then under(field, value)
-
else raise "Invalid operation: #{op}"
-
end
-
6
self
-
end
-
-
1
def where(properties = {})
-
56
properties.each do |es_code, value|
-
49
field = check_field_exists es_code
-
-
48
if value.is_a? String
-
case
-
5
when value[0 .. 1] == '<=' then lte(field, value[2 .. -1].strip)
-
1
when value[0] == '<' then lt(field, value[1 .. -1].strip)
-
1
when value[0 .. 1] == '>=' then gte(field, value[2 .. -1].strip)
-
2
when value[0] == '>' then gt(field, value[1 .. -1].strip)
-
4
when value[0] == '=' then eq(field, value[1 .. -1].strip)
-
4
when value[0 .. 1] == '~=' then starts_with(field, value[2 .. -1].strip)
-
13
else eq(field, value)
-
30
end
-
elsif value.is_a? Hash
-
8
value.each { |pair| op(field, pair[0], pair[1]) }
-
else
-
14
eq(field, value)
-
end
-
end
-
48
self
-
end
-
-
-
# Set a really large number for site parameter, since ES does not have a way to return all terms matching the hits
-
# https://github.com/elasticsearch/elasticsearch/issues/1776
-
# The number I put here is the max integer in Java
-
1
def histogram_search(field_es_code, filters=nil)
-
facets_hash = {
-
terms: {
-
field: field_es_code,
-
size: 2147483647,
-
all_terms: true,
-
}
-
}
-
-
if filters.present?
-
query_params = query_params(filters.keys.first, filters.values.first)
-
query_hash = {facet_filter: {and: [query_params]} }
-
facets_hash.merge!(query_hash)
-
end
-
-
add_facet "field_#{field_es_code}_ratings", facets_hash
-
-
self
-
end
-
-
-
1
def before(time)
-
2
time = parse_time(time)
-
2
add_filter range: {updated_at: {lte: Site.format_date(time)}}
-
2
self
-
end
-
-
1
def after(time)
-
2
time = parse_time(time)
-
2
updated_since_query(time)
-
end
-
-
1
def updated_since(iso_string)
-
time = Time.iso8601(iso_string)
-
updated_since_query(time)
-
end
-
-
1
def updated_since_query(time)
-
2
add_filter range: {updated_at: {gte: Site.format_date(time)}}
-
2
self
-
end
-
-
1
def alerted_search(v)
-
add_filter term: {alert: v}
-
self
-
end
-
-
1
def date_query(iso_string, field_name)
-
# We use a 2 seconds range, not the exact date, because this would be very restrictive
-
time = Time.iso8601(iso_string)
-
time_upper_bound = time + 1.second
-
time_lower_bound = time - 1.second
-
add_filter range: {field_name.to_sym => {gte: Site.format_date(time_lower_bound)}}
-
add_filter range: {field_name.to_sym => {lte: Site.format_date(time_upper_bound)}}
-
self
-
end
-
-
1
def updated_at(iso_string)
-
date_query(iso_string, 'updated_at')
-
end
-
-
1
def created_at(iso_string)
-
date_query(iso_string, 'created_at')
-
end
-
-
1
def full_text_search(text)
-
22
query = ElasticSearch::QueryHelper.full_text_search(text, self, collection, fields)
-
22
add_query query_string: {query: query} if query
-
22
self
-
end
-
-
1
def box(west, south, east, north)
-
1
add_filter geo_bounding_box: {
-
location: {
-
top_left: {
-
lat: north,
-
lon: west
-
},
-
bottom_right: {
-
lat: south,
-
lon: east
-
},
-
}
-
}
-
1
self
-
end
-
-
1
def radius(lat, lng, meters)
-
4
meters = meters.to_f unless meters.is_a?(String) && (meters.end_with?('km') || meters.end_with?('mi'))
-
4
add_filter geo_distance: {
-
distance: meters,
-
location: { lat: lat, lon: lng }
-
}
-
4
self
-
end
-
-
1
def field_exists(field_code)
-
add_filter exists: {field: field_code}
-
end
-
-
1
def require_location
-
2
add_filter exists: {field: :location}
-
2
self
-
end
-
-
1
def location_missing
-
1
add_filter not: {exists: {field: :location}}
-
1
self
-
end
-
-
1
def hierarchy(es_code, value)
-
6
field = check_field_exists es_code
-
6
if value.present?
-
3
eq field, value
-
else
-
3
add_filter not: {exists: {field: es_code}}
-
end
-
end
-
-
1
def get_body
-
126
body = {}
-
-
126
if @filters
-
87
if @filters.length == 1
-
66
body[:filter] = @filters.first
-
else
-
21
body[:filter] = {and: @filters}
-
end
-
end
-
-
126
if @facets
-
body[:facets] = @facets
-
end
-
-
126
all_queries = []
-
-
126
if @prefixes
-
7
prefixes = @prefixes.map { |prefix| {prefix: {prefix[:key] => prefix[:value]}} }
-
3
all_queries.concat prefixes
-
end
-
-
126
if @queries
-
17
all_queries.concat @queries
-
end
-
-
126
case all_queries.length
-
when 0
-
# Nothing to do
-
when 1
-
19
body[:query] = all_queries.first
-
else
-
1
body[:query] = {bool: {must: all_queries}}
-
end
-
-
126
body
-
end
-
-
1
def select_fields(fields_array)
-
2
@select_fields = fields_array
-
2
self
-
end
-
-
1
def add_filter(filter)
-
110
@filters ||= []
-
110
@filters.push filter
-
end
-
-
1
def add_facet(name, value)
-
@facets ||= {}
-
@facets[name] = value
-
end
-
-
1
private
-
-
1
def decode(code)
-
3
return code unless @use_codes_instead_of_es_codes
-
-
3
code = remove_at_from_code code
-
6
fields.find { |x| x.code == code }.es_code
-
end
-
-
1
def remove_at_from_code(code)
-
27
code.start_with?('@') ? code[1 .. -1] : code
-
end
-
-
1
def add_query(query)
-
17
@queries ||= []
-
17
@queries.push query
-
end
-
-
1
def add_prefix(query)
-
4
@prefixes ||= []
-
4
@prefixes.push query
-
end
-
-
1
def parse_time(time)
-
4
if time.is_a? String
-
2
time = case time
-
when /last(_|\s*)hour/i then Time.now - 1.hour
-
when /last(_|\s*)day/i then Time.now - 1.day
-
when /last(_|\s*)week/i then Time.now - 1.week
-
when /last(_|\s*)month/i then Time.now - 1.month
-
2
else Time.parse(time)
-
end
-
end
-
4
time
-
end
-
-
1
def check_field_exists(code)
-
55
if @use_codes_instead_of_es_codes
-
21
code = remove_at_from_code code
-
167
fields_with_code = fields.select{|f| f.code == code}
-
21
raise "Unknown field: #{code}" unless fields_with_code.length > 0
-
21
fields_with_code[0]
-
else
-
171
fields_with_es_code = fields.select{|f| f.es_code == code}
-
34
raise "Unknown field: #{code}" unless fields_with_es_code.length > 0
-
33
fields_with_es_code[0]
-
end
-
end
-
-
1
def fields
-
83
@_fields_ ||= collection.fields
-
end
-
-
1
def to_curl(client, body)
-
126
info = client.transport.hosts.first
-
126
protocol, host, port = info[:protocol], info[:host], info[:port]
-
-
126
url = "#{protocol}://#{host}:#{port}/#{@index_names}/site/_search"
-
-
126
body = body.to_json.gsub("'",'\u0027')
-
126
"curl -X GET '#{url}?pretty' -d '#{body}'"
-
end
-
end
-
1
require 'strscan'
-
-
# Represents a search. It's a hash of key value pairs plus a search string.
-
#
-
# Examples:
-
# Search.new('hello') => search = 'hello', {}
-
# Search.new('key:value') => search = nil, {:key => 'value'}
-
# Search.new('key:"many words"') => search = nil, {:key => 'many words'}
-
# Search.new('something key:"many words"') => search = 'something', {:key => 'many words'}
-
# Search.new('sms://foo') => search = 'sms://foo', {}
-
# Search.new('from:sms://foo') => search = nil, {:from => 'sms://foo'}
-
#
-
1
class SearchParser < Hash
-
1
attr_reader :search
-
-
1
def initialize(str)
-
44
return if str.nil?
-
-
43
s = StringScanner.new(str.to_s)
-
-
43
until s.eos?
-
# Skip whitespace
-
58
s.scan(/\s+/)
-
-
#Scan decimal number for location full-text-searches
-
58
key = scan_decimal_number(s)
-
-
# Get next work
-
58
key = s.scan(/\w+/) if key.nil?
-
-
# Check if there's a colon so we have key:...
-
# (but not key://)
-
58
colon = s.scan(/:/)
-
58
if colon
-
# Check key:"value"
-
14
value = s.scan(/".+?"/)
-
14
value = value ? value[1...-1] : s.scan(/(\S)+/)
-
14
self[key] = value
-
14
next
-
end
-
-
44
key = s.scan(/"(\w|\s)+"/) if key.nil?
-
44
key = s.scan(/\W+/) if key.nil?
-
-
# Just a word to add to the search
-
44
add_to_search key
-
end
-
end
-
-
1
def scan_decimal_number(string_scanner)
-
# Is string_scanner a location that starts with hyphen?
-
58
key_with_hyphen = string_scanner.scan(/-\d+.\d+/)
-
#Remove hyphen
-
58
key = key_with_hyphen[1..-1] if key_with_hyphen
-
-
#Is string_scanner a location
-
58
key = string_scanner.scan(/\d+.\d+/) if key.nil?
-
58
key
-
end
-
-
1
def add_to_search(value)
-
44
@search = @search ? "#{@search} #{value}" : value
-
end
-
-
1
def self.get_op_and_val(val)
-
5
op = '='
-
5
if val.length > 1 && (val[0..1] == '<=' || val[0..1] == '>=')
-
1
op = val[0..1]
-
1
val = val[2..-1]
-
elsif val.length > 0 && (val[0].chr == '<' || val[0].chr == '>')
-
1
op = val[0].chr
-
1
val = val[1..-1]
-
end
-
5
[op, val]
-
end
-
end
-
1
class ShareNationalChannel < ActiveRecord::Base
-
1
belongs_to :user
-
1
belongs_to :collection
-
1
belongs_to :channel
-
-
end
-
1
class Site < ActiveRecord::Base
-
1
include Activity::AwareConcern
-
1
include Site::ActivityConcern
-
1
include Site::CleanupConcern
-
1
include Site::GeomConcern
-
1
include Site::PrefixConcern
-
1
include Site::ElasticsearchConcern
-
1
include HistoryConcern
-
-
1
belongs_to :collection
-
761
validates_presence_of :name, :if => Proc.new {collection.is_visible_name}
-
-
1
serialize :properties, Hash
-
1
validate :valid_properties
-
1
after_validation :standardize_properties
-
1
before_validation :assign_default_values, :on => :create
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
attr_accessor :from_import_wizard
-
-
1
def history_concern_foreign_key
-
697
self.class.name.foreign_key
-
end
-
-
1
def extended_properties
-
1394
@extended_properties ||= Hash.new
-
end
-
-
1
def update_properties(site, user, props)
-
props.each do |p|
-
field = Field.where(:collection_id => site.collection.id, :code => p.values[0]).first
-
site.properties[field.id.to_s] = p.values[1]
-
end
-
site.save!
-
end
-
-
1
def human_properties
-
1
fields = collection.fields.index_by(&:es_code)
-
-
1
props = {}
-
1
properties.each do |key, value|
-
3
field = fields[key]
-
3
if field
-
3
props[field.name] = field.human_value value
-
else
-
props[key] = value
-
end
-
end
-
1
props
-
end
-
-
1
def self.get_id_and_name sites
-
1
sites = Site.select("id, name").find(sites)
-
1
sites_with_id_and_name = []
-
1
sites.each do |site|
-
1
site_with_id_and_name = {
-
"id" => site.id,
-
"name" => site.name
-
}
-
1
sites_with_id_and_name.push site_with_id_and_name
-
end
-
1
sites_with_id_and_name
-
end
-
-
1
def self.create_or_update_from_hash! hash
-
3
site = Site.where(:id => hash["site_id"]).first_or_initialize
-
3
site.prepare_attributes_from_hash!(hash)
-
3
site.save ? site : nil
-
end
-
-
1
def prepare_attributes_from_hash!(hash)
-
3
self.collection_id = hash["collection_id"]
-
3
self.name = hash["name"]
-
3
self.lat = hash["lat"]
-
3
self.lng = hash["lng"]
-
3
self.user = hash["current_user"]
-
3
properties = {}
-
3
hash["existing_fields"].each_value do |field|
-
6
properties[field["field_id"].to_s] = field["value"]
-
end
-
3
self.properties = properties
-
end
-
-
1
def filter_site_by_id site_id
-
2
builder = Site.find site_id
-
end
-
-
1
def validate_and_process_parameters(site_params, user)
-
user_membership = user.membership_in(collection)
-
-
if site_params.has_key?("name")
-
user.authorize! :update_name, user_membership, message: "Not authorized to update site name"
-
self.name = site_params["name"]
-
end
-
-
if site_params.has_key?("lng")
-
user.authorize! :update_location, user_membership, message: "Not authorized to update site location"
-
self.lng = site_params["lng"]
-
end
-
-
if site_params.has_key?("lat")
-
user.authorize! :update_location, user_membership, message: "Not authorized to update site location"
-
self.lat = site_params["lat"]
-
end
-
-
if site_params.has_key?("properties")
-
fields_by_es_code = collection.fields.index_by(&:es_code)
-
fields_by_code = collection.fields.index_by(&:code)
-
-
properties_will_change!
-
-
site_params["properties"].each_pair do |es_code_or_code, value|
-
field = fields_by_es_code[es_code_or_code] || fields_by_code[es_code_or_code]
-
-
# Next if there is no changes in the property
-
next if value == self.properties[field.es_code]
-
-
user.authorize! :update_site_property, field, message: "Not authorized to update site property with code #{es_code_or_code}"
-
self.properties[field.es_code] = field.decode_from_ui(value)
-
end
-
end
-
-
# after, so if the user update the whole site
-
# the auto_reset is reseted
-
if self.changed?
-
self.assign_default_values_for_update
-
end
-
end
-
-
1
def assign_default_values_for_update
-
fields = collection.fields.index_by(&:es_code)
-
-
fields.each do |es_code, field|
-
value = field.default_value_for_update
-
properties[field.es_code] = value unless value.nil?
-
end
-
self
-
end
-
-
1
def assign_default_values_for_create
-
fields = collection.fields.index_by(&:es_code)
-
-
fields.each do |es_code, field|
-
if properties[field.es_code].blank?
-
value = field.default_value_for_create(collection)
-
properties[field.es_code] = value if value
-
end
-
end
-
self
-
end
-
-
1
private
-
-
1
def standardize_properties
-
760
fields = collection.fields.index_by(&:es_code)
-
-
760
standardized_properties = {}
-
760
properties.each do |es_code, value|
-
1185
field = fields[es_code]
-
1185
if field
-
1184
standardized_properties[es_code] = field.standadrize(value)
-
end
-
end
-
760
self.properties = standardized_properties
-
end
-
-
1
def assign_default_values
-
672
fields = collection.fields.index_by(&:es_code)
-
-
672
fields.each do |es_code, field|
-
2809
if properties[field.es_code].blank?
-
1740
value = field.default_value_for_create(collection)
-
1740
properties[field.es_code] = value if value
-
end
-
end
-
end
-
-
1
def valid_properties
-
760
return unless valid_lat_lng
-
760
fields = collection.fields.index_by(&:es_code)
-
760
fields_mandatory = collection.fields.where(is_mandatory: true)
-
760
properties.each do |es_code, value|
-
1185
field = fields[es_code]
-
1185
if field
-
1184
begin
-
1184
field.valid_value?(value, self)
-
rescue => ex
-
9
errors.add(:properties, {field.es_code => ex.message})
-
end
-
-
1184
fields_mandatory.each do |f|
-
if f.id.to_s == es_code.to_s
-
fields_mandatory.delete f
-
end
-
end
-
end
-
end
-
760
fields_mandatory.each do |f|
-
errors.add(:properties, {f.id.to_s => "#{f.code} is required."})
-
end
-
end
-
-
1
def valid_lat_lng
-
764
valid = true
-
764
if collection.is_visible_location
-
-
764
if lat
-
714
if (lat >= -90) && (lat <= 90)
-
712
valid = true
-
else
-
2
errors.add(:lat, "latitude must be in the range of -90 to 90")
-
2
return false
-
end
-
end
-
-
762
if lng
-
712
if (lng >= -180) && (lng <= 180)
-
712
valid = true
-
else
-
errors.add(:lng, "longitude must be in the range of -180 to 180")
-
return false
-
end
-
end
-
-
end
-
762
return valid
-
end
-
end
-
1
module Site::ActivityConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
after_create :create_created_activity, :unless => :mute_activities
-
1
before_update :record_name_was, :unless => :mute_activities
-
1
after_update :create_updated_activity, :unless => :mute_activities
-
1
after_destroy :create_deleted_activity, :unless => :mute_activities, :if => :user
-
end
-
-
1
def create_created_activity
-
634
site_data = {'name' => @name_was || name}
-
634
site_data['lat'] = lat if lat
-
634
site_data['lng'] = lng if lng
-
634
site_data['properties'] = properties if properties.present?
-
634
Activity.create! item_type: 'site', action: 'created', collection_id: collection.id, site_id: id, user_id: user.id, data: site_data
-
end
-
-
1
def record_name_was
-
59
@name_was = name_was
-
end
-
-
1
def create_updated_activity
-
-
59
site_changes = changes.except('updated_at', 'min_lat', 'max_lat', 'min_lng', 'max_lng', 'min_zoom', 'max_zoom').to_hash
-
-
# If either lat or lng change we want to singal a change in both, as in "location changed" and
-
# we can show what the location was before and was it now without consulting the site's properties
-
59
site_changes['lat'] = [lat, lat] if !site_changes['lat'] && site_changes['lng']
-
59
site_changes['lng'] = [lng, lng] if site_changes['lat'] && !site_changes['lng']
-
-
59
unless location_changed(site_changes)
-
50
site_changes.delete 'lat'
-
50
site_changes.delete 'lng'
-
end
-
-
# This is the case of properties => [{}, {}]
-
59
if site_changes['properties']
-
199
2.times { |i| site_changes['properties'][i].reject! { |k, v| v.nil? } }
-
30
if site_changes['properties'][0] == site_changes['properties'][1]
-
site_changes.delete 'properties'
-
end
-
end
-
-
59
if site_changes.present?
-
54
site = Site.find(id)
-
54
Activity.create! item_type: 'site',
-
action: 'changed',
-
collection_id: collection.id,
-
user_id: user.id,
-
site_id: id,
-
data: { "name" => @name_was || name,
-
"changes" => site_changes ,
-
"properties" => site.properties,
-
"lat" => site.lat,
-
"lng" => site.lng
-
}
-
-
end
-
end
-
-
1
def location_changed(changes)
-
# This code assumes that 'lat' is a property of 'changes' iff 'lng' is,
-
# and that if one is set to/from nil, the other is too.
-
59
if changes['lat']
-
10
if changes['lat'][0] && changes['lat'][1]
-
8
return (changes['lat'][0] - changes['lat'][1]).abs >= 1e-04 ||
-
9
(changes['lng'][0] - changes['lng'][1]).abs >= 1e-04
-
else
-
2
return changes['lat'][0] != changes['lat'][1]
-
end
-
else
-
49
return false
-
end
-
end
-
-
1
def create_deleted_activity
-
5
Activity.create! item_type: 'site', action: 'deleted', collection_id: collection.id, user_id: user.id, site_id: id, 'data' => {'name' => name}
-
end
-
end
-
1
module Site::CleanupConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
before_validation :remove_blank_properties, :if => :properties
-
end
-
-
1
def remove_blank_properties
-
# False values are not rejected for the case of yes_no fields with value false, witch may be different for the ones without value.
-
1954
self.properties.reject! { |k, v| v!= false && v.blank? }
-
end
-
end
-
1
module Site::ElasticsearchConcern
-
1
extend ActiveSupport::Concern
-
-
1
DateFormat = "%Y%m%dT%H%M%S.%L%z"
-
-
1
included do
-
1
after_save :store_in_index
-
1
after_destroy :remove_from_index
-
1
define_model_callbacks :index
-
1
delegate :index_name, to: :collection
-
end
-
-
1
def store_in_index(options = {})
-
697
run_callbacks :index do
-
697
Site::IndexUtils.store self, id, index_name, options
-
end
-
end
-
-
1
def to_elastic_search
-
Site::IndexUtils.to_elastic_search(self, id)
-
end
-
-
1
def from_index
-
search = collection.new_search
-
search.id id
-
search.results.first
-
end
-
-
1
def remove_from_index
-
6
client = Elasticsearch::Client.new
-
6
client.delete index: index_name, id: id, type: 'site'
-
6
client.indices.refresh index: index_name
-
end
-
-
1
module ClassMethods
-
1
def parse_time(es_time_string)
-
22
if es_time_string.bytesize == 24
-
# Optimization for when the string has 24 chars, which should
-
# be something like this: 20140522T063835.000+0000
-
# This is the format we store datetimes in Elasticsearch, so
-
# the `else` part of the if shouldn't execute, but just in case...
-
22
year = es_time_string[0, 4].to_i
-
22
month = es_time_string[4, 2].to_i
-
22
day = es_time_string[6, 2].to_i
-
22
hour = es_time_string[9, 2].to_i
-
22
minute = es_time_string[11, 2].to_i
-
22
second = es_time_string[13, 2].to_i
-
22
offset = es_time_string[19 .. -1].to_i
-
22
time = Time.new(year, month, day, hour, minute, second, offset)
-
22
ActiveSupport::TimeWithZone.new(time.utc, Time.zone)
-
else
-
Time.zone.parse(es_time_string)
-
end
-
end
-
-
1
def iso_string_to_rfc822(iso_string, time_zone = nil)
-
6
date = DateTime.strptime iso_string, DateFormat
-
6
date = date.in_time_zone time_zone if time_zone
-
6
date.rfc822
-
end
-
-
1
def format_date(date)
-
4
date.strftime DateFormat
-
end
-
end
-
end
-
1
module Site::GeomConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
698
after_save :compute_collection_bounding_box!, :if => lambda { (new_record? || lat_changed? || lng_changed?) && !from_import_wizard }
-
1
after_destroy :compute_collection_bounding_box!
-
end
-
-
1
def compute_collection_bounding_box!
-
620
collection.compute_bounding_box!
-
end
-
end
-
1
module Site::IndexUtils
-
1
extend self
-
-
1
DateFormat = "%Y%m%dT%H%M%S.%L%z"
-
1
DefaultIndexSettings = {
-
settings: {
-
index: {
-
analysis: {
-
analyzer: {
-
default_index: {
-
tokenizer: :standard,
-
filter: [:lowercase, :preserving_asciifolding],
-
type: :custom
-
},
-
downcase: {
-
tokenizer: :keyword,
-
filter: [:lowercase],
-
type: :custom
-
}
-
},
-
filter: {
-
preserving_asciifolding: {
-
type: :asciifolding,
-
preserve_original: true
-
}
-
}
-
}
-
}
-
}
-
}
-
-
1
class DefaultStrategy
-
1
def self.store(document, index_name, options = {})
-
698
client = Elasticsearch::Client.new
-
698
result = client.index index: index_name, type: 'site', id: document[:id], body: document
-
698
if result['error']
-
raise "Can't store site in index: #{result['error']}"
-
end
-
-
698
unless options[:refresh] == false
-
698
client.indices.refresh index: index_name
-
end
-
end
-
end
-
-
1
class BulkStrategy
-
1
def initialize
-
@documents = []
-
@client = Elasticsearch::Client.new
-
end
-
-
1
def store(document, index_name, options = {})
-
@documents.push index: { _index: index_name, _type: 'site', _id: document[:id]}
-
@documents.push document
-
-
flush if @documents.length >= 2000
-
end
-
-
1
def flush
-
@client.bulk body: @documents
-
@documents.clear
-
end
-
end
-
-
1
def self.strategy
-
698
Thread.current[:index_utils_strategy] || DefaultStrategy
-
end
-
-
1
def self.strategy=(strategy)
-
Thread.current[:index_utils_strategy] = strategy
-
end
-
-
1
def self.bulk
-
self.strategy = BulkStrategy.new
-
yield
-
ensure
-
self.strategy.flush
-
self.strategy = nil
-
end
-
-
1
def store(site, site_id, index_name, options = {})
-
698
document = to_elastic_search(site, site_id)
-
698
Site::IndexUtils.strategy.store(document, index_name, options)
-
end
-
-
1
def to_elastic_search(site, site_id)
-
712
hash = {
-
id: site_id,
-
name: site.name,
-
id_with_prefix: site.id_with_prefix,
-
uuid: site.uuid,
-
type: :site,
-
properties: site.properties,
-
created_at: site.created_at.utc.strftime(DateFormat),
-
updated_at: site.updated_at.utc.strftime(DateFormat),
-
icon: site.collection.icon,
-
# If the migration to add the version in Sites is not runned, then calling site.version will cause some previous migration to fail
-
712
version: (site.version rescue nil)
-
}
-
-
712
alert = site.collection.thresholds_test site unless self.is_a? SiteHistory
-
712
if alert != nil
-
hash[:alert] = true
-
hash[:color] = alert.color
-
hash[:ord] = alert.ord
-
else
-
712
hash[:alert] = false
-
end
-
-
712
if site.lat && site.lng
-
684
hash[:location] = {lat: site.lat.to_f, lon: site.lng.to_f}
-
684
hash[:lat_analyzed] = site.lat.to_s
-
684
hash[:lng_analyzed] = site.lng.to_s
-
end
-
712
hash.merge! site.extended_properties if site.is_a? Site
-
712
hash
-
end
-
-
1
def site_mapping(fields)
-
{
-
properties: {
-
name: {
-
type: :multi_field,
-
fields: {
-
name: { type: :string },
-
downcase: { type: :string, index: :analyzed, analyzer: :downcase },
-
},
-
},
-
id_with_prefix: { type: :string },
-
uuid: { type: :string, index: :not_analyzed },
-
location: { type: :geo_point },
-
lat_analyzed: { type: :string },
-
lng_analyzed: { type: :string },
-
created_at: { type: :date, format: :basic_date_time },
-
updated_at: { type: :date, format: :basic_date_time },
-
properties: { properties: fields_mapping(fields) },
-
version: { type: :long }
-
}
-
2682
}
-
end
-
-
1
def fields_mapping(fields)
-
5049
fields.each_with_object({}) { |field, hash| hash[field.es_code] = field.index_mapping }
-
end
-
end
-
1
module Site::PrefixConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
before_create :assign_id_with_prefix
-
end
-
-
1
def assign_id_with_prefix
-
637
self.id_with_prefix = generate_id_with_prefix if self.id_with_prefix.nil?
-
end
-
-
1
def generate_id_with_prefix
-
619
site = Site.where('id_with_prefix is not null').where(collection_id: self.collection_id).last
-
619
if site.nil?
-
301
id_with_prefix = [Prefix.next.version,1]
-
else
-
318
id_with_prefix = site.get_id_with_prefix
-
318
id_with_prefix[1].next!
-
end
-
619
id_with_prefix.join
-
end
-
-
1
def get_id_with_prefix
-
319
assign_id_with_prefix unless id_with_prefix
-
319
self.id_with_prefix.split /(\d+)/
-
end
-
end
-
1
module Site::UploadUtils
-
1
extend self
-
1
require 'rmagick'
-
-
1
def uploadSingleFile(key, value)
-
img = Magick::Image::from_blob(value).first
-
img.resize_to_fit!(800)
-
path = "public/photo_field/"
-
Dir.mkdir(path) unless File.exists?(path)
-
img.write(path + key)
-
end
-
-
1
def uploadFile(fileHash)
-
if fileHash
-
fileHash.each do |key, value|
-
img = Magick::Image::from_blob(Base64.decode64(value)).first
-
img.resize_to_fit!(800)
-
path = "public/photo_field/"
-
Dir.mkdir(path) unless File.exists?(path)
-
img.write(path + key)
-
end
-
end
-
end
-
-
1
def purgePhotos(photosToRemove)
-
path = "public/photo_field/"
-
photosToRemove.each { |photo|
-
photoFileName = path + photo
-
if File.exists?(photoFileName)
-
File.delete(photoFileName)
-
end
-
}
-
end
-
-
1
def purgeUploadedPhotos(site)
-
1
photoFields = Field.where(:collection_id => site.collection_id, :kind => 'photo')
-
1
photoFields.each { |field|
-
path = "public/photo_field/"
-
photoFileName = site.properties[field.id.to_s]
-
if !photoFileName.nil? and File.exists?(path + photoFileName)
-
File.delete(path + photoFileName)
-
end
-
}
-
-
end
-
-
end
-
1
class SiteHistory < ActiveRecord::Base
-
1
belongs_to :site
-
1
belongs_to :collection
-
-
1
serialize :properties, Hash
-
-
1
def store_in(index)
-
1
Site::IndexUtils.store self, site_id, index
-
end
-
-
1
def to_elastic_search
-
14
Site::IndexUtils.to_elastic_search(self, site_id)
-
end
-
end
-
1
class SiteReminder < ActiveRecord::Base
-
1
belongs_to :reminder
-
1
belongs_to :site
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
private
-
-
1
def touch_collection_lifespan
-
5
Telemetry::Lifespan.touch_collection self.site.try(:collection)
-
end
-
end
-
1
class SitesPermission < ActiveRecord::Base
-
1
belongs_to :membership
-
1
serialize :some_sites, Array
-
-
1
after_save :touch_membership_lifespan
-
1
after_destroy :touch_membership_lifespan
-
-
1
def as_json(options = {})
-
17
super options.merge({except: [:id, :membership_id, :created_at, :updated_at]})
-
end
-
-
1
def self.no_permission
-
3
{ read: nil, write: nil }
-
end
-
end
-
1
class Snapshot < ActiveRecord::Base
-
1
belongs_to :collection
-
1
has_many :user_snapshots, dependent: :destroy
-
-
1
validates_presence_of :name
-
1
validates_uniqueness_of :name, :scope => :collection_id
-
-
1
after_create :create_index
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
def create_index
-
41
index_properties = {
-
mappings: { site: site_mapping }
-
}
-
41
index_properties.merge!(Site::IndexUtils::DefaultIndexSettings)
-
-
41
client = Elasticsearch::Client.new
-
41
client.indices.create index: index_name, body: index_properties
-
-
41
docs = collection.site_histories.at_date(date).map do |history|
-
14
history.collection = collection
-
14
history.to_elastic_search
-
end
-
41
docs.each_slice(200) do |docs_slice|
-
6
ops = []
-
6
docs_slice.each do |doc|
-
14
ops.push index: { _index: index_name, _type: 'site', _id: doc[:id]}
-
14
ops.push doc
-
end
-
6
client.bulk body: ops
-
end
-
# client.indices.refresh
-
end
-
-
1
after_destroy :destroy_index
-
-
1
def destroy_index
-
3
Elasticsearch::Client.new.indices.delete index: index_name
-
end
-
-
1
def index_name
-
58
collection.index_name snapshot_id: id
-
end
-
-
1
def recreate_index
-
destroy_index rescue nil
-
create_index
-
end
-
-
1
def fields
-
41
collection.field_histories.at_date(date)
-
end
-
-
1
def site_mapping
-
41
Site::IndexUtils.site_mapping fields
-
end
-
-
# Given some collections and a user, returns a Hash collection_id => snapshot_name.
-
1
def self.names_for_collections_and_user(collections, user)
-
info_for_collections_ids_and_user(collections.map(&:id), user, "name")
-
end
-
-
# Given some collections and a user, returns a Hash collection_id => snapshot_id.
-
1
def self.ids_for_collections_ids_and_user(collections_ids, user)
-
info_for_collections_ids_and_user(collections_ids, user, "id")
-
end
-
-
1
def self.info_for_collections_ids_and_user(collections_ids, user, field)
-
1
collections_ids = collections_ids.map { |id| connection.quote(id) }.join ', '
-
1
user_id = connection.quote(user.id)
-
-
1
return {} unless collections_ids.length > 0
-
-
results = connection.execute("
-
select c.id, s.#{field}
-
from collections c, user_snapshots u, snapshots s
-
where c.id = u.collection_id and u.snapshot_id = s.id
-
and u.user_id = #{user_id}
-
and c.id IN (#{collections_ids})")
-
Hash[results.to_a]
-
end
-
end
-
1
module Telemetry::ActivitiesCollector
-
-
1
def self.collect_stats(period)
-
4
period_end = ActiveRecord::Base.sanitize(period.end)
-
-
4
results = ActiveRecord::Base.connection.execute <<-SQL
-
SELECT collections.id, COUNT(activities.collection_id)
-
FROM collections
-
LEFT JOIN activities ON activities.collection_id = collections.id
-
AND activities.created_at < #{period_end}
-
WHERE collections.created_at < #{period_end}
-
GROUP BY collections.id
-
SQL
-
-
{
-
"counters" => results.map { |collection_id, count|
-
{
-
"metric" => "activities",
-
"key" => { "collection_id" => collection_id },
-
"value" => count
-
6
}
-
}
-
4
}
-
end
-
-
-
end
-
1
module Telemetry::AlertConditionsCollector
-
-
1
def self.collect_stats(period)
-
# Count for collections that have thresholds
-
4
counts = Hash.new(0)
-
-
4
Threshold.where('created_at < ?', period.end).find_each do |t|
-
6
counts[t.collection_id] += t.conditions.size
-
end
-
-
# Count for collections that don't have thresholds
-
4
period_end = ActiveRecord::Base.sanitize(period.end)
-
-
4
empty_results = ActiveRecord::Base.connection.execute <<-SQL
-
SELECT collections.id
-
FROM collections
-
LEFT JOIN thresholds ON thresholds.collection_id = collections.id
-
AND thresholds.created_at < #{period_end}
-
WHERE collections.created_at < #{period_end}
-
AND thresholds.collection_id IS NULL
-
SQL
-
-
# Join results
-
4
counters = counts.map do |collection_id, count|
-
{
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => collection_id },
-
"value" => count
-
4
}
-
end
-
-
4
empty_counters = empty_results.map do |collection_id, _|
-
{
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => collection_id },
-
"value" => 0
-
2
}
-
end
-
-
-
4
{ "counters" => counters.concat(empty_counters) }
-
end
-
-
end
-
1
module Telemetry::FieldsCollector
-
-
1
def self.collect_stats(period)
-
2
period_end = ActiveRecord::Base.sanitize(period.end)
-
-
2
results = ActiveRecord::Base.connection.execute <<-SQL
-
SELECT collections.id, COUNT(fields.collection_id)
-
FROM collections
-
LEFT JOIN fields ON fields.collection_id = collections.id
-
AND fields.created_at < #{period_end}
-
WHERE collections.created_at < #{period_end}
-
GROUP BY collections.id
-
SQL
-
-
2
counters = results.map do |collection_id, count|
-
{
-
metric: 'fields_by_collection',
-
key: {collection_id: collection_id},
-
value: count
-
4
}
-
end
-
-
2
{counters: counters}
-
end
-
-
end
-
1
module Telemetry::Lifespan
-
1
def self.touch_collection(collection)
-
5497
if collection.present?
-
5477
InsteddTelemetry.timespan_update('collection_lifespan', {collection_id: collection.id}, collection.created_at, Time.now.utc)
-
-
5477
collection.users.each do |user|
-
4262
self.touch_user(user)
-
end
-
end
-
end
-
-
1
def self.touch_user(user)
-
6698
InsteddTelemetry.timespan_update('account_lifespan', {account_id: user.id}, user.created_at, Time.now.utc) if user.present?
-
end
-
end
-
1
module Telemetry::MembershipsCollector
-
-
1
def self.collect_stats(period)
-
4
period_end = ActiveRecord::Base.sanitize(period.end)
-
-
4
results = ActiveRecord::Base.connection.execute <<-SQL
-
SELECT collections.id, COUNT(memberships.collection_id)
-
FROM collections
-
LEFT JOIN memberships ON memberships.collection_id = collections.id
-
AND memberships.created_at < #{period_end}
-
WHERE collections.created_at < #{period_end}
-
GROUP BY collections.id
-
SQL
-
-
{
-
"counters" => results.map { |collection_id, count|
-
{
-
"metric" => "memberships",
-
"key" => { "collection_id" => collection_id },
-
"value" => count
-
6
}
-
}
-
4
}
-
end
-
-
-
end
-
1
module Telemetry::NewCollectionsCollector
-
-
1
def self.collect_stats(period)
-
3
count = Collection.where("created_at >= ?", period.beginning)
-
.where("created_at < ?", period.end)
-
.count
-
{
-
"counters" => [
-
{
-
"metric" => "new_collections",
-
"key" => {},
-
"value" => count
-
}
-
]
-
3
}
-
end
-
-
-
end
-
1
module Telemetry::SitesCollector
-
-
1
def self.collect_stats(period)
-
4
period_end = ActiveRecord::Base.sanitize(period.end)
-
-
4
results = ActiveRecord::Base.connection.execute <<-SQL
-
SELECT collections.id, COUNT(sites.collection_id)
-
FROM collections
-
LEFT JOIN sites ON sites.collection_id = collections.id
-
AND sites.created_at < #{period_end}
-
WHERE collections.created_at < #{period_end}
-
GROUP BY collections.id
-
SQL
-
-
{
-
"counters" => results.map { |collection_id, count|
-
{
-
"metric" => "sites",
-
"key" => { "collection_id" => collection_id },
-
"value" => count
-
6
}
-
}
-
4
}
-
end
-
-
-
end
-
1
class User < ActiveRecord::Base
-
1
devise :database_authenticatable, :registerable,
-
:recoverable, :rememberable, :trackable, :validatable, :confirmable,
-
:omniauthable
-
-
# Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me, :phone_number
-
1
has_many :memberships, :dependent => :destroy
-
1
has_many :channels
-
61
has_many :collections, -> { order('collections.name ASC')}, through: :memberships
-
1
has_one :user_snapshot
-
1
has_many :identities, dependent: :destroy
-
-
1
validates_uniqueness_of :phone_number, :allow_blank => true
-
1681
validates_strength_of :password, :with => :email, :if => lambda {|u| u.password.present?}
-
-
1
has_many :share_national_channels
-
-
1
attr_accessor :is_guest
-
-
1
before_save :ensure_authentication_token
-
-
1
after_save :touch_lifespan
-
1
after_destroy :touch_lifespan
-
-
1
def ensure_authentication_token
-
1691
if !self.authentication_token
-
1677
self.authentication_token = generate_authentication_token
-
end
-
end
-
-
1
def ability(format = nil)
-
@ability ||= Ability.new(self, format)
-
end
-
1
delegate :can?, :cannot?, :authorize!, :to => :ability
-
-
1
def create_collection(collection)
-
394
return false unless collection.save
-
393
memberships.create! collection_id: collection.id, admin: true, owner: true
-
393
collection.register_gateways_under_user_owner(self)
-
393
collection
-
end
-
-
1
def admins?(collection)
-
18
memberships.where(:collection_id => collection.id).first.try(:admin?)
-
end
-
-
1
def belongs_to?(collection)
-
memberships.where(:collection_id => collection.id).exists?
-
end
-
-
1
def membership_in(collection)
-
86
memberships.where(:collection_id => collection.id).first
-
end
-
-
1
def display_name
-
email
-
end
-
-
1
def can_write_field?(field, collection, field_es_code)
-
23
return false unless field
-
-
22
membership = membership_in(collection)
-
22
return true if membership.admin?
-
-
2
lm = LayerMembership.where(user_id: self.id, collection_id: collection.id, layer_id: field.layer_id).first
-
2
lm && lm.write
-
end
-
-
1
def activities
-
2
Activity.where(collection_id: memberships.pluck(:collection_id))
-
end
-
-
1
def can_view?(collection, option)
-
10
return collection.public if collection.public
-
9
membership = self.memberships.where(:collection_id => collection.id).first
-
9
return false unless membership
-
8
return membership.admin if membership.admin
-
-
8
return true if(validate_layer_read_permission(collection, option))
-
false
-
end
-
-
1
def can_update?(site, properties)
-
9
membership = self.memberships.where(:collection_id => site.collection_id).first
-
9
return false unless membership
-
7
return membership.admin if membership.admin?
-
4
return true if(validate_layer_write_permission(site, properties))
-
false
-
end
-
-
1
def can_add?(collection_id)
-
3
membership = self.memberships.where(:collection_id => collection_id).first
-
3
return false unless membership
-
3
return membership.admin if membership.admin?
-
end
-
-
1
def validate_layer_write_permission(site, properties)
-
7
properties.each do |prop|
-
7
field = Field.where("code=? && collection_id=?", prop.values[0].to_s, site.collection_id).first
-
7
return false if field.nil?
-
7
lm = LayerMembership.where(user_id: self.id, collection_id: site.collection_id, layer_id: field.layer_id).first
-
7
return false if lm.nil?
-
6
return false if(lm.write == false)
-
end
-
6
return true
-
end
-
-
1
def validate_layer_read_permission(collection, field_code)
-
10
field = Field.where("code=? && collection_id=?", field_code, collection.id).first
-
10
return false if field.nil?
-
9
lm = LayerMembership.where(user_id: self.id, collection_id: collection.id, layer_id: field.layer_id).first
-
9
return false if lm.nil?
-
9
return false if(!lm && lm.read)
-
9
return true
-
end
-
-
1
def self.encrypt_users_password
-
2
all.each { |user| user.update_attributes password: user.encrypted_password }
-
end
-
-
1
def get_gateway
-
2
channels.first
-
end
-
-
1
def active_gateway
-
channels.where("channels.is_enable=?", true)
-
end
-
-
1
def update_successful_outcome_status
-
12
self.success_outcome = layer_count? & collection_count? & site_count? & gateway_count?
-
end
-
-
1
def register_guest_membership(collection_id)
-
membership = self.memberships.find_by_collection_id collection_id
-
self.memberships.create! collection_id: collection_id, admin: false if(!membership)
-
end
-
-
1
def self.generate_random_password
-
Devise.friendly_token.first(6)
-
end
-
-
1
def self.generate_default_email
-
email_order_number_array = []
-
emails = User.where("email like ?", "%default-%").select("email")
-
if (emails.count > 0)
-
emails.each do |el|
-
email = el.email
-
end_index = email.index("@") - 1
-
start_index = email.index("-") + 1
-
email_order_number = Integer(email[start_index..end_index])
-
email_order_number_array << email_order_number
-
end
-
max_order = email_order_number_array.max + 1
-
else
-
max_order = 1
-
end
-
return "default-#{max_order}@example.com"
-
end
-
-
1
def self.generate_user_display_name user
-
if user.email.index("default-")
-
display_name = user.phone_number
-
else
-
display_name = user.email
-
end
-
return display_name
-
end
-
-
1
private
-
-
1
def generate_authentication_token
-
1677
loop do
-
1677
token = Devise.friendly_token
-
1677
break token unless User.where(authentication_token: token).first
-
end
-
end
-
-
1
def touch_lifespan
-
1692
Telemetry::Lifespan.touch_user self
-
end
-
end
-
1
class UserSnapshot < ActiveRecord::Base
-
1
belongs_to :snapshot
-
1
belongs_to :user
-
1
belongs_to :collection
-
-
1
before_create :destroy_previous_for_user_and_collection
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
1
after_save :touch_user_lifespan
-
1
after_destroy :touch_user_lifespan
-
-
1
def destroy_previous_for_user_and_collection
-
34
UserSnapshot.destroy_all user_id: self.user_id, collection_id: self.collection_id
-
end
-
-
1
def go_back_to_present!
-
5
self.snapshot_id = nil
-
5
self.save! unless self.new_record?
-
end
-
-
# Loads the given collection snapshot for the related user.
-
# Returns false if there's no such a snapshot.
-
# Returns true if it succeeds.
-
1
def go_to!(snapshot_name)
-
3
snapshot_to_load = collection.snapshots.where(:name => snapshot_name).first
-
-
3
return false unless snapshot_to_load
-
-
2
self.snapshot_id = snapshot_to_load.id
-
2
self.save!
-
-
2
true
-
end
-
-
1
def at_present?
-
30
self.snapshot_id.nil?
-
end
-
-
1
def self.for(user, collection)
-
28
user_snapshot = UserSnapshot.where(user_id: user.id, collection_id: collection.id).first
-
# user_snapshot ||= UserSnapshot.new user: user, collection: collection
-
28
unless user_snapshot
-
27
user_snapshot = UserSnapshot.new
-
27
user_snapshot.user = user
-
27
user_snapshot.collection = collection
-
end
-
28
user_snapshot
-
end
-
end
-
1
class WriteSitesPermission < SitesPermission; end
-
1
class Xform
-
1
FORMAT = {
-
:model => "<field-%1$d><field-id>%1$d</field-id><value /></field-%1$d>",
-
:binding => "<bind nodeset=\"/site/existing-fields/field-%s/value\" />",
-
:ui => "<input ref=\"/site/existing-fields/field-%1$d/value\"><label>%2$s</label></input>"
-
}
-
-
1
attr_reader :template
-
-
1
def initialize(template = nil)
-
7
@template = template
-
end
-
-
1
def render_form(collection)
-
7
fields = collection.fields
-
@template.gsub(
-
"%(:title)", collection.name).gsub(
-
"%(:collection_id)", collection.id.to_s).gsub(
-
"%(:existing_fields)", render_model(fields)).gsub(
-
7
"%(:existing_fields_binding)", render_binding(fields)).gsub(
-
7
"%(:existing_fields_ui)", render_ui(fields)) unless @template.nil?
-
end
-
-
1
def render_model(fields)
-
7
render(fields, :model) do |field, format|
-
14
sprintf(format, field.id)
-
end
-
end
-
-
1
def render_binding(fields)
-
7
render(fields, :binding) do |field, format|
-
14
sprintf(format, field.id)
-
end
-
end
-
-
1
def render_ui(fields)
-
7
render(fields, :ui) do |field, format|
-
14
sprintf(format, field.id, field.name)
-
end
-
end
-
-
1
private
-
1
def render(fields, format, &block)
-
21
content = ""
-
21
if block_given?
-
21
fields.each do |field|
-
42
content << yield(field, FORMAT[format])
-
end
-
end
-
21
content
-
end
-
-
end
-
1
class SmsNuntium
-
1
def self.notify_sms users_phone_number, message, suggested_channel, collection_id
-
1
nuntium_messages = []
-
1
users_phone_number.each do |phone_number|
-
1
nuntium_message = {
-
:from =>"resourcemap",
-
:to => "sms://#{phone_number}",
-
:body => message,
-
:suggested_channel => suggested_channel
-
}
-
1
nuntium_messages.push nuntium_message
-
end
-
1
nuntium = Nuntium.new_from_config
-
1
nuntium.send_ao nuntium_messages
-
1
Message.log nuntium_messages, collection_id if collection_id
-
end
-
end
-
1
require File.expand_path('../boot', __FILE__)
-
-
1
require 'rails/all'
-
1
require "openid"
-
1
require 'openid/extensions/sreg'
-
1
require 'openid/extensions/pape'
-
1
require 'openid/store/filesystem'
-
1
require 'net/http'
-
-
1
if defined?(Bundler)
-
# If you precompile assets before deploying to production, use this line
-
1
Bundler.require(*Rails.groups(:assets => %w(development test)))
-
# If you want your assets lazily compiled in production, use this line
-
# Bundler.require(:default, :assets, Rails.env)
-
end
-
-
1
module ResourceMap
-
1
class Application < Rails::Application
-
# Settings in config/environments/* take precedence over those specified here.
-
# Application configuration should go into files in config/initializers
-
# -- all .rb files in that directory are automatically loaded.
-
-
# Custom directories with classes and modules you want to be autoloadable.
-
# config.autoload_paths += %W(#{config.root}/extras)
-
1
config.autoload_paths += Dir["#{config.root}/plugins"]
-
1
config.autoload_paths += Dir["#{config.root}/plugins/*/{controllers,models,workers}"]
-
1
config.autoload_paths += %W(#{Rails.root}/lib/extras)
-
-
# Load all Field classes to make associations like "text_fields" and "numeric_fields" work
-
1
config.to_prepare do
-
1
Dir[ File.expand_path(Rails.root.join("app/models/field/*.rb")) ].each do |file|
-
15
require_dependency file
-
end
-
end
-
-
# Only load the plugins named here, in the order given (default is alphabetical).
-
# :all can be used as a placeholder for all plugins not explicitly named.
-
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
-
-
# Activate observers that should always be running.
-
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
-
-
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
-
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
-
# config.time_zone = 'Central Time (US & Canada)'
-
-
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
-
1
config.i18n.enforce_available_locales = false
-
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
-
# config.i18n.default_locale = :de
-
1
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
-
1
config.i18n.default_locale = :en
-
-
# Configure the default encoding used in templates for Ruby 1.9.
-
1
config.encoding = "utf-8"
-
-
# Configure sensitive parameters which will be filtered from the log file.
-
1
config.filter_parameters += [:password]
-
-
# Use SQL instead of Active Record's schema dumper when creating the database.
-
# This is necessary if your schema can't be completely dumped by the schema dumper,
-
# like if you have constraints or database-specific column types
-
# config.active_record.schema_format = :sql
-
-
# Enforce whitelist mode for mass assignment.
-
# This will create an empty whitelist of attributes available for mass-assignment for all models
-
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
-
# parameters by using an attr_accessible or attr_protected declaration.
-
1
config.active_record.whitelist_attributes = false
-
-
# Enable the asset pipeline
-
1
config.assets.enabled = true
-
-
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
-
# config.assets.precompile += %w( jquery.mobile-1.3.1.min.css jquery.js jquery_ujs.js knockout-2.2.1.js custom_bindings/mobileenable.js mobile/mobilecache.js mobile/collections.js mobile/events.js jquery.mobile-1.3.1.min.js mobile.js )
-
1
config.assets.precompile += %w( mobile.js mobile.css jquery.mobile-1.3.2.js jquery.mobile-1.3.2.css )
-
-
# Version of your assets, change this if you want to expire all your assets
-
1
config.assets.version = '1.0'
-
-
1
config.action_mailer.delivery_method = :sendmail
-
1
config.google_analytics = 'UA-17030081-1'
-
-
1
config.version_name = `git describe --abbrev=0 --tags` rescue "Development"
-
1
config.revision = File.read('REVISION').strip rescue "Development"
-
-
1
config.middleware.insert_before 0, "Rack::Cors" do
-
1
allow do
-
1
origins '*'
-
1
resource '*', :headers => :any, :methods => [:get, :post, :options]
-
end
-
end
-
-
end
-
end
-
1
require 'rubygems'
-
1
require 'yaml'
-
-
# Set up gems listed in the Gemfile.
-
1
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
-
-
1
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
-
-
1
module Settings
-
1
extend self
-
-
1
CONFIG = YAML.load_file(File.expand_path('../settings.yml', __FILE__))
-
-
1
def is_on?(plugin)
-
707
plugins[plugin.to_s] == true
-
end
-
-
1
def selected_plugins
-
plugins.map{|k,v| k if v == true }.compact
-
end
-
-
1
def method_missing(method_name)
-
720
if method_name.to_s =~ /(\w+)\?$/
-
2
CONFIG[$1] == true
-
else
-
718
CONFIG[method_name.to_s]
-
end
-
end
-
end
-
-
1
module RecaptchaSetting
-
1
extend self
-
-
1
CONFIG = YAML.load_file(File.expand_path('../recaptcha.yml', __FILE__))
-
-
1
def method_missing(method_name)
-
if method_name.to_s =~ /(\w+)\?$/
-
CONFIG[Rails.env][$1] == true
-
else
-
CONFIG[Rails.env][method_name.to_s]
-
end
-
end
-
-
1
def validate_captcha(key, challeng, response)
-
uri = URI('#{Settings.protocol}://www.google.com/recaptcha/api/verify')
-
params = { :privatekey => key, :remoteip => Settings.host, :challenge => challeng, :response => response }
-
res = Net::HTTP.post_form(uri, params)
-
end
-
-
end
-
-
# Load the rails application
-
1
require File.expand_path('../application', __FILE__)
-
-
# Initialize the rails application
-
1
ResourceMap::Application.initialize!
-
1
ResourceMap::Application.configure do
-
# Settings specified here will take precedence over those in config/application.rb
-
-
# The test environment is used exclusively to run your application's
-
# test suite. You never need to work with it otherwise. Remember that
-
# your test database is "scratch space" for the test suite and is wiped
-
# and recreated between test runs. Don't rely on the data there!
-
1
config.cache_classes = true
-
-
# Configure static asset server for tests with Cache-Control for performance
-
1
config.serve_static_assets = true
-
1
config.static_cache_control = "public, max-age=3600"
-
-
# Log error messages when you accidentally call methods on nil
-
1
config.whiny_nils = true
-
-
# Show full error reports and disable caching
-
1
config.consider_all_requests_local = true
-
1
config.action_controller.perform_caching = false
-
-
# Raise exceptions instead of rendering exception templates
-
1
config.action_dispatch.show_exceptions = false
-
-
# Disable request forgery protection in test environment
-
1
config.action_controller.allow_forgery_protection = false
-
-
# Tell Action Mailer not to deliver emails to the real world.
-
# The :test delivery method accumulates sent emails in the
-
# ActionMailer::Base.deliveries array.
-
1
config.action_mailer.delivery_method = :test
-
1
config.action_mailer.default_url_options = { :host => Settings.host }
-
-
# Raise exception on mass assignment protection for Active Record models
-
1
config.active_record.mass_assignment_sanitizer = :strict
-
-
# Print deprecation notices to the stderr
-
1
config.active_support.deprecation = :stderr
-
-
1
config.eager_load = false
-
end
-
1
require 'active_record_telemetry'
-
# Be sure to restart your server when you modify this file.
-
-
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
-
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
-
-
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
-
# Rails.backtrace_cleaner.remove_silencers!
-
1
if Rails.env == 'development' || Rails.env == 'test'
-
1
def $stdout.puts_with_color(*args)
-
4
print "\033[1;32m"
-
4
puts_without_color *args
-
4
print "\033[0m"
-
end
-
-
2
klass = class << $stdout; self; end
-
1
klass.alias_method_chain :puts, :color
-
-
1
module Kernel
-
1
def p_with_color(*args)
-
print "\033[1;32m"
-
p_without_color *args
-
print "\033[0m"
-
end
-
1
alias_method_chain :p, :color
-
end
-
end
-
1
require 'csv'
-
-
# Patch CSV class to try to open the file with the correct encoding.
-
1
class CSV
-
-
1
def initialize_with_encoding(data, options = {})
-
# Try to parse the file using utf-8 encoding.
-
# If it's not valid, we assume it's latin1 (Windows default)
-
193
options[:encoding] ||= 'utf-8'
-
193
begin
-
193
initialize_without_encoding data, options
-
1
rescue => ex
-
1
options[:encoding] = 'ISO-8859-1:utf-8'
-
1
data.rewind if data.respond_to? :rewind
-
1
initialize_without_encoding data, options
-
end
-
end
-
1
alias_method_chain :initialize, :encoding
-
-
1
class << self
-
1
def open_with_encoding(*args, &block)
-
113
options = if args.last.is_a? Hash then args.pop else Hash.new end
-
-
# Try to parse the file using utf-8 encoding.
-
# If it's not valid, we assume it's latin1 (Windows default)
-
113
options[:encoding] ||= 'utf-8'
-
113
begin
-
113
open_without_encoding *(args + [options]), &block
-
rescue
-
1
options[:encoding] = 'ISO-8859-1:utf-8'
-
1
open_without_encoding *(args + [options]), &block
-
end
-
end
-
1
alias_method_chain :open, :encoding
-
end
-
end
-
1
module CanCan
-
1
class ControllerResource
-
-
1
def resource_instance
-
12
if load_instance?
-
10
if use_decent_exposure?
-
10
@controller.send(instance_name)
-
else
-
@controller.instance_variable_get("@#{instance_name}")
-
end
-
end
-
-
end
-
-
1
def use_decent_exposure?
-
10
@options[:decent_exposure] && @controller.respond_to?(instance_name)
-
end
-
-
end
-
end
-
# Use this hook to configure devise mailer, warden hooks and so forth.
-
# Many of these configuration options can be set straight in your model.
-
1
ActionController::Responder.class_eval do
-
1
alias :to_mobile :to_html
-
end
-
1
Devise.setup do |config|
-
# ==> Mailer Configuration
-
# Configure the e-mail address which will be shown in Devise::Mailer,
-
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
-
1
config.mailer_sender = "resourcemap@instedd.org"
-
-
# Configure the class responsible to send e-mails.
-
# config.mailer = "Devise::Mailer"
-
-
# ==> ORM configuration
-
# Load and configure the ORM. Supports :active_record (default) and
-
# :mongoid (bson_ext recommended) by default. Other ORMs may be
-
# available as additional gems.
-
1
require 'devise/orm/active_record'
-
-
# ==> Configuration for any authentication mechanism
-
# Configure which keys are used when authenticating a user. The default is
-
# just :email. You can configure it to use [:username, :subdomain], so for
-
# authenticating a user, both parameters are required. Remember that those
-
# parameters are used only when authenticating and not when retrieving from
-
# session. If you need permissions, you should implement that in a before filter.
-
# You can also supply a hash where the value is a boolean determining whether
-
# or not authentication should be aborted when the value is not present.
-
1
config.authentication_keys = [ :email ]
-
-
# Configure parameters from the request object used for authentication. Each entry
-
# given should be a request method and it will automatically be passed to the
-
# find_for_authentication method and considered in your model lookup. For instance,
-
# if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
-
# The same considerations mentioned for authentication_keys also apply to request_keys.
-
# config.request_keys = []
-
-
# Configure which authentication keys should be case-insensitive.
-
# These keys will be downcased upon creating or modifying a user and when used
-
# to authenticate or find a user. Default is :email.
-
1
config.case_insensitive_keys = [ :email ]
-
-
# Configure which authentication keys should have whitespace stripped.
-
# These keys will have whitespace before and after removed upon creating or
-
# modifying a user and when used to authenticate or find a user. Default is :email.
-
1
config.strip_whitespace_keys = [ :email ]
-
-
# Tell if authentication through request.params is enabled. True by default.
-
# It can be set to an array that will enable params authentication only for the
-
# given strategies, for example, `config.params_authenticatable = [:database]` will
-
# enable it only for database (email + password) authentication.
-
# config.params_authenticatable = true
-
-
# Tell if authentication through HTTP Basic Auth is enabled. False by default.
-
# It can be set to an array that will enable http authentication only for the
-
# given strategies, for example, `config.http_authenticatable = [:token]` will
-
# enable it only for token authentication.
-
1
config.http_authenticatable = true
-
-
# If http headers should be returned for AJAX requests. True by default.
-
# config.http_authenticatable_on_xhr = true
-
-
# The realm used in Http Basic Authentication. "Application" by default.
-
# config.http_authentication_realm = "Application"
-
-
# It will change confirmation, password recovery and other workflows
-
# to behave the same regardless if the e-mail provided was right or wrong.
-
# Does not affect registerable.
-
# config.paranoid = true
-
-
# By default Devise will store the user in session. You can skip storage for
-
# :http_auth and :token_auth by adding those symbols to the array below.
-
# Notice that if you are skipping storage for all authentication paths, you
-
# may want to disable generating routes to Devise's sessions controller by
-
# passing :skip => :sessions to `devise_for` in your config/routes.rb
-
1
config.skip_session_storage = [:token_auth]
-
-
# ==> Configuration for :database_authenticatable
-
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
-
# using other encryptors, it sets how many times you want the password re-encrypted.
-
#
-
# Limiting the stretches to just one in testing will increase the performance of
-
# your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
-
# a value less than 10 in other environments.
-
1
config.stretches = Rails.env.test? ? 1 : 10
-
-
# Setup a pepper to generate the encrypted password.
-
1
config.pepper = "db5c4ca9ac7df4fe3a4bdaf668f06be5863f8b5e420f2f615159a940cd056b5b9eb4838eb952a9b84650e020750f737ba179047a93c41820557c9385730691df"
-
-
# ==> Configuration for :confirmable
-
# A period that the user is allowed to access the website even without
-
# confirming his account. For instance, if set to 2.days, the user will be
-
# able to access the website for two days without confirming his account,
-
# access will be blocked just in the third day. Default is 0.days, meaning
-
# the user cannot access the website without confirming his account.
-
# config.allow_unconfirmed_access_for = 2.days
-
-
# If true, requires any email changes to be confirmed (exactly the same way as
-
# initial account confirmation) to be applied. Requires additional unconfirmed_email
-
# db field (see migrations). Until confirmed new email is stored in
-
# unconfirmed email column, and copied to email column on successful confirmation.
-
1
config.reconfirmable = true
-
-
# Defines which key will be used when confirming an account
-
# config.confirmation_keys = [ :email ]
-
-
# ==> Configuration for :rememberable
-
# The time the user will be remembered without asking for credentials again.
-
# config.remember_for = 2.weeks
-
-
# If true, extends the user's remember period when remembered via cookie.
-
# config.extend_remember_period = false
-
-
# Options to be passed to the created cookie. For instance, you can set
-
# :secure => true in order to force SSL only cookies.
-
# config.rememberable_options = {}
-
-
# ==> Configuration for :validatable
-
# Range for password length. Default is 6..128.
-
1
config.password_length = 1..128
-
-
# Email regex used to validate email formats. It simply asserts that
-
# an one (and only one) @ exists in the given string. This is mainly
-
# to give user feedback and not to assert the e-mail validity.
-
# config.email_regexp = /\A[^@]+@[^@]+\z/
-
-
# ==> Configuration for :timeoutable
-
# The time you want to timeout the user session without activity. After this
-
# time the user will be asked for credentials again. Default is 30 minutes.
-
# config.timeout_in = 30.minutes
-
-
# ==> Configuration for :lockable
-
# Defines which strategy will be used to lock an account.
-
# :failed_attempts = Locks an account after a number of failed attempts to sign in.
-
# :none = No lock strategy. You should handle locking by yourself.
-
# config.lock_strategy = :failed_attempts
-
-
# Defines which key will be used when locking and unlocking an account
-
# config.unlock_keys = [ :email ]
-
-
# Defines which strategy will be used to unlock an account.
-
# :email = Sends an unlock link to the user email
-
# :time = Re-enables login after a certain amount of time (see :unlock_in below)
-
# :both = Enables both strategies
-
# :none = No unlock strategy. You should handle unlocking by yourself.
-
# config.unlock_strategy = :both
-
-
# Number of authentication tries before locking an account if lock_strategy
-
# is failed attempts.
-
# config.maximum_attempts = 20
-
-
# Time interval to unlock the account if :time is enabled as unlock_strategy.
-
# config.unlock_in = 1.hour
-
-
# ==> Configuration for :recoverable
-
#
-
# Defines which key will be used when recovering the password for an account
-
# config.reset_password_keys = [ :email ]
-
-
# Time interval you can reset your password with a reset password key.
-
# Don't put a too small interval or your users won't have the time to
-
# change their passwords.
-
1
config.reset_password_within = 6.hours
-
-
# ==> Configuration for :encryptable
-
# Allow you to use another encryption algorithm besides bcrypt (default). You can use
-
# :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
-
# :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
-
# and :restful_authentication_sha1 (then you should set stretches to 10, and copy
-
# REST_AUTH_SITE_KEY to pepper)
-
# config.encryptor = :sha512
-
-
# ==> Configuration for :token_authenticatable
-
# Defines name of the authentication token params key
-
# config.token_authentication_key = :auth_token
-
1
config.secret_key = '6490002751d1ecf6d65bf71aafacda43888e2c68c9607ee37f101430aa904429364e3f4b12c7242d13e045cb6305374a9cf359c63ef43e1955e872b4bd4f9c0d'
-
# ==> Scopes configuration
-
# Turn scoped views on. Before rendering "sessions/new", it will first check for
-
# "users/sessions/new". It's turned off by default because it's slower if you
-
# are using only default views.
-
# config.scoped_views = false
-
-
# Configure the default scope given to Warden. By default it's the first
-
# devise role declared in your routes (usually :user).
-
# config.default_scope = :user
-
-
# Configure sign_out behavior.
-
# Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope).
-
# The default is true, which means any logout action will sign out all active scopes.
-
# config.sign_out_all_scopes = true
-
-
# ==> Navigation configuration
-
# Lists the formats that should be treated as navigational. Formats like
-
# :html, should redirect to the sign in page when the user does not have
-
# access, but formats like :xml or :json, should return 401.
-
#
-
# If you have any extra navigational formats, like :iphone or :mobile, you
-
# should add them to the navigational formats lists.
-
#
-
# The "*/*" below is required to match Internet Explorer requests.
-
# config.navigational_formats = ["*/*", :html]
-
-
# The default HTTP method used to sign out a resource. Default is :delete.
-
1
config.sign_out_via = :delete
-
-
# ==> OmniAuth
-
# Add a new OmniAuth provider. Check the wiki for more information on setting
-
# up on your models and hooks.
-
# config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
-
-
# ==> Warden configuration
-
# If you want to use other strategies, that are not supported by Devise, or
-
# change the failure app, you can configure them inside the config.warden block.
-
#
-
# config.warden do |manager|
-
# manager.intercept_401 = false
-
# manager.default_strategies(:scope => :user).unshift :some_external_strategy
-
# end
-
end
-
# epsg.io - Coordinate Systems Worldwide
-
# http://epsg.io
-
-
1
module Epsg
-
1
extend self
-
-
1
COORDINATE_SYSTEMS = {
-
'4326' => 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]' }.freeze
-
-
1
def [] key
-
4
esri = COORDINATE_SYSTEMS[key.to_s]
-
unless esri
-
2
res = Net::HTTP.get_response URI "http://epsg.io/#{key}.esriwkt"
-
2
res.body if res.code == '200'
-
4
end || esri
-
end
-
-
# Named alias for epsg:4326
-
# http://epsg.io/4326
-
1
def wgs84
-
1
self['4326']
-
end
-
end
-
1
GoogleMapsKey = File.read("#{Rails.root}/config/google_maps.key") rescue ""
-
# Be sure to restart your server when you modify this file.
-
-
# Add new inflection rules using the following format
-
# (all these examples are active by default):
-
# ActiveSupport::Inflector.inflections do |inflect|
-
# inflect.plural /^(ox)$/i, '\1en'
-
# inflect.singular /^(ox)en/i, '\1'
-
# inflect.irregular 'person', 'people'
-
# inflect.uncountable %w( fish sheep )
-
# end
-
#
-
# These inflection rules are supported but not enabled by default:
-
# ActiveSupport::Inflector.inflections do |inflect|
-
# inflect.acronym 'RESTful'
-
# end
-
1
InsteddTelemetry.setup do |config|
-
# Telemetry server URL
-
1
config.server_url = "http://telemetry.instedd.org"
-
-
1
config_path = File.join(Rails.root, 'config', 'telemetry.yml')
-
1
custom_config = File.exists?(config_path) ? YAML.load_file(config_path).with_indifferent_access : nil
-
-
1
if custom_config.present?
-
config.server_url = custom_config[:server_url] if custom_config.include? :server_url
-
config.period_size = custom_config[:period_size_hours].hours if custom_config.include? :period_size_hours
-
config.process_run_interval = custom_config[:run_interval_minutes].minutes if custom_config.include? :run_interval_minutes
-
end
-
# Add custom collectors to Telemetry
-
1
config.add_collector Telemetry::ActivitiesCollector
-
1
config.add_collector Telemetry::AlertConditionsCollector
-
1
config.add_collector Telemetry::MembershipsCollector
-
1
config.add_collector Telemetry::NewCollectionsCollector
-
1
config.add_collector Telemetry::SitesCollector
-
1
config.add_collector Telemetry::FieldsCollector
-
-
end
-
1
LanguageOptions = [{:code => "en", :id => 1, :name => "English"}, {:id =>2 , :code => "kh", :name => "Khmer"}]
-
# Be sure to restart your server when you modify this file.
-
-
# Add new mime types for use in respond_to blocks:
-
# Mime::Type.register "text/richtext", :rtf
-
# Mime::Type.register_alias "text/html", :iphone
-
1
Mime::Type.register_alias "text/html", :mobile
-
1
Mime::Type.register 'application/vnd.google-earth.kml+xml', :kml
-
1
Mime::Type.register "application/zip", :shp
-
1
class Nuntium
-
1
Config = YAML.load_file(File.expand_path('../../../config/nuntium.yml', __FILE__))[Rails.env]
-
-
1
def self.new_from_config
-
Nuntium.new Config['url'], Config['account'], Config['application'], Config['password']
-
end
-
-
1
def self.config
-
Config
-
end
-
-
end
-
1
class Object
-
1
def to_i_or_f
-
6
Integer(self)
-
rescue
-
2
Float(self) rescue nil
-
end
-
end
-
1
Oj.default_options = {mode: :compat, bigdecimal_load: :float }
-
-
1
class Object
-
1
def to_json_oj
-
2
Oj.dump self
-
end
-
end
-
-
1
MultiJson.use :oj
-
1
ActionDispatch::Reloader.to_prepare do
-
1
Dir["#{Rails.root}/plugins/*"].each do |plugin_dir|
-
4
plugin_name = File.basename plugin_dir
-
4
plugin_name.camelize.constantize::Plugin.instance
-
-
4
ActionController::Base.append_view_path "#{plugin_dir}/views"
-
4
Dir["#{plugin_dir}/assets/*"].each do |assets_dir|
-
10
Rails.configuration.assets.paths << assets_dir
-
10
Rails.configuration.assets.precompile << "#{plugin_name}.js"
-
10
Rails.configuration.assets.precompile << "#{plugin_name}.css"
-
end
-
-
4
if Rails.env == "development" || Rails.env == "test"
-
4
Rails.configuration.assets.paths << "#{plugin_dir}/spec/javascripts"
-
end
-
-
4
Dir["#{plugin_dir}/controllers/**.rb"].each do |controller_file|
-
4
controller_class_name = File.basename controller_file, '.*'
-
4
controller_class = controller_class_name.camelize.constantize
-
4
next unless controller_class.ancestors.include? ActionController::Base
-
-
4
controller_class.class_eval %Q(
-
def initialize
-
prepend_view_path "#{plugin_dir}/views"
-
super
-
end
-
)
-
end
-
# load plugins/{plug_in_name}/locales/
-
4
Rails.configuration.i18n.load_path += Dir[File.join(plugin_dir, 'locales', '**', '*.{rb,yml}').to_s]
-
end
-
-
1
Plugin.hooks(:extend_model).each do |extension|
-
5
extension[:class].send :include, extension[:with]
-
end
-
end
-
-
1
class ActiveRecord::Migrator
-
1
cattr_accessor :current_plugin
-
-
1
class << self
-
-
1
def migrations_paths_with_plugins
-
if current_plugin
-
["plugins/#{current_plugin}/db/migrate"]
-
else
-
migrations_paths_without_plugins
-
end
-
end
-
1
alias_method_chain :migrations_paths, :plugins
-
-
1
def get_all_versions_with_plugins
-
return get_all_versions_without_plugins unless current_plugin
-
table = Arel::Table.new(schema_migrations_table_name)
-
ActiveRecord::Base.connection.select_values(table.project(table['version'])).select{ |v| v.match(/-#{current_plugin}/) }.map{ |v| v.to_i }.sort
-
end
-
1
alias_method_chain :get_all_versions, :plugins
-
-
end
-
-
1
def record_version_state_after_migrating_with_plugins(version)
-
return record_version_state_after_migrating_without_plugins(version) unless current_plugin
-
record_version_state_after_migrating_without_plugins(version.to_s + "-" + current_plugin.to_s)
-
end
-
1
alias_method_chain :record_version_state_after_migrating, :plugins
-
end
-
# require 'resque_scheduler'
-
# require 'resque_scheduler/server'
-
-
1
ActionDispatch::Reloader.to_prepare do
-
2
Resque.schedule = Hash[*Plugin.hooks(:schedule).map {|x| [x[:class].underscore, x.with_indifferent_access]}.flatten]
-
end
-
-
# Be sure to restart your server when you modify this file.
-
-
# Your secret key for verifying the integrity of signed cookies.
-
# If you change this key, all old signed cookies will become invalid!
-
# Make sure the secret is at least 30 characters and all random,
-
# no regular words or you'll be exposed to dictionary attacks.
-
1
ResourceMap::Application.config.secret_token = '7fe0756c76a4de31e9f56c2853aa6a694470088427153aaf1d76694f0132d00424b927cc5d445c010899fed8993e3409fc5f687591c48dc1a3f24cbe13e31df1'
-
1
ResourceMap::Application.config.secret_key_base = 'b559cc822922e2b750a02167f1016a77c3a2a7198584a4ad9b0d7dde15ea56a3c0b7596109aa2911a3100e9374e39253d50df12780f279d80cb7e39e6129b948'
-
# Be sure to restart your server when you modify this file.
-
-
1
ResourceMap::Application.config.session_store :cookie_store, key: '_resource_map_session'
-
-
# Use the database for sessions instead of the cookie-based default,
-
# which shouldn't be used to store highly confidential information
-
# (create the session table with "rails generate session_migration")
-
# ResourceMap::Application.config.session_store :active_record_store
-
#require 'geo_ruby/shp'
-
-
#::Dbf = GeoRuby::Shp4r::Dbf
-
#::ShpFile = GeoRuby::Shp4r::ShpFile
-
#::ShpType = GeoRuby::Shp4r::ShpType
-
#::Point = GeoRuby::SimpleFeatures::Point
-
#::ShpRecord = GeoRuby::Shp4r::ShpRecord
-
1
class String
-
# Does this string represent an integer?
-
1
def integer?
-
167
Integer(self) rescue nil
-
end
-
-
1
def real?
-
10
Float(self) rescue nil
-
end
-
-
1
def render_template_string(option_hash)
-
1
self.gsub(/\[[\w\s\?.,_\-()]+\]/) do |template|
-
2
option_hash.each do |key, value|
-
3
if template == '['+ key+ ']'
-
2
if key == "Site Name"
-
1
template = value
-
else
-
1
template = value
-
end
-
2
break
-
end
-
end
-
2
template
-
end
-
end
-
-
1
def is_integer?
-
self.to_i.to_s == self
-
end
-
-
1
def is_float?
-
self.to_f.to_s == self
-
end
-
-
end
-
# Tire::Configuration.wrapper Hash
-
-
# prefix method exists in Tire since revision 995ea29,
-
# but wasn't released to the public at the time of this writing.
-
-
# class Tire::Search::Query
-
# def prefix(field, value, options={})
-
# if options[:boost]
-
# @value = { :prefix => { field => { :prefix => value, :boost => options[:boost] } } }
-
# else
-
# @value = { :prefix => { field => value } }
-
# end
-
# end
-
# end
-
-
# class Tire::Search::Search
-
# def stream
-
# uri = URI(url)
-
# reader, writer = IO.pipe
-
# producer = Thread.new(writer) do |io|
-
# Net::HTTP.start(uri.host, uri.port) do |http|
-
# request = Net::HTTP::Get.new uri.request_uri
-
# http.request request, to_json do |response|
-
# response.read_body { |segment| io.write segment }
-
# end
-
# io.close
-
# end
-
# end
-
# reader
-
# end
-
# end
-
-
# class Tire::Index
-
# def update_mapping(mapping)
-
# mapping.each do |type, value|
-
# url, body = "#{Tire::Configuration.url}/#{@name}/#{type}/_mapping", MultiJson.encode(type => value)
-
# begin
-
# @response = Tire::Configuration.client.put url, body
-
# raise RuntimeError, "#{@response.code} > #{@response.body}" if @response.failure?
-
# ensure
-
# curl = %Q|curl -X PUT "#{url}" -d '#{body}'|
-
# logged('MAPPING', curl)
-
# end
-
# end
-
# true
-
# end
-
# end
-
-
# module Tire
-
# def self.delete_indices_that_match(regex)
-
# indexes = JSON.parse Tire::Configuration.client.get("#{Tire::Configuration.url}/_status").body
-
# indexes['indices'].each do |name, index|
-
# Tire::Index.new(name).delete if name =~ regex
-
# end
-
# end
-
# end
-
# Be sure to restart your server when you modify this file.
-
#
-
# This file contains settings for ActionController::ParamsWrapper which
-
# is enabled by default.
-
-
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
-
1
ActiveSupport.on_load(:action_controller) do
-
1
wrap_parameters format: [:json]
-
end
-
-
# Disable root element in JSON by default.
-
1
ActiveSupport.on_load(:active_record) do
-
1
self.include_root_in_json = false
-
end
-
1
ResourceMap::Application.routes.draw do
-
-
1
mount InsteddTelemetry::Engine => '/instedd_telemetry'
-
# devise_for :users, :controllers => {:registrations => "registrations", :sessions => 'sessions' }
-
1
devise_for :users, controllers: {registrations: "registrations", omniauth_callbacks: "omniauth_callbacks"}
-
1
guisso_for :user
-
-
# match 'messaging' => 'messaging#index'
-
1
match 'nuntium' => 'nuntium#receive', :via => :post
-
1
match 'authenticate' => 'nuntium#authenticate', :via => :post
-
1
match 'android/collections' => 'android#collections_json', :via => :get
-
1
match 'android/submission' => 'android#submission', :via => :post
-
1
match 'collections/breadcrumbs' => 'collections#render_breadcrumbs', :via => :post
-
1
match 'real-time-resource-tracking' => 'home#second_page', :via => :get
-
1
match 'track-medical-supplies-and-personnel'=> 'home#medical_page', :via => :get
-
1
match 'track-food-prices-and-supplies' => 'home#food_page', :via => :get
-
1
match 'collections/alerted-collections' => 'collections#alerted_collections', :via => :get
-
#match 'analytics' => 'analytics#index', :via => :get
-
1
get 'download/activity' => "activities#download"
-
1
match 'get_user_auth_token' => "application#get_user_auth_token", :via => 'get'
-
1
match 'load_app_cache' => 'home#load_app_cache', :via => 'get'
-
1
get 'plugin/alerts/thresholds' => 'thresholds#index'
-
1
get 'channels_accesses/search_user'
-
1
get 'channels_accesses/search_collection'
-
-
1
resources :repeats
-
1
resources :collections do
-
1
post :send_new_member_sms
-
1
post :register_gateways
-
1
get :message_quota
-
1
get :sites_by_term
-
1
resources :sites do
-
1
get :visible_layers_for
-
end
-
1
resources :layers do
-
-
1
member do
-
1
put :set_order
-
end
-
-
1
collection do
-
1
post :upload_layers
-
1
get :adjust_layers
-
1
get :pending_layers
-
end
-
end
-
1
resources :fields
-
-
1
resources :memberships do
-
1
collection do
-
1
get 'invitable'
-
1
get 'search'
-
end
-
1
member do
-
1
post 'set_layer_access'
-
1
post 'set_admin'
-
1
post 'unset_admin'
-
end
-
end
-
1
resources :sites_permission
-
-
1
get 'members'
-
1
get 'settings'
-
1
get 'quotas'
-
1
get 'csv_template'
-
1
get 'max_value_of_property'
-
-
1
post 'upload_csv'
-
-
1
post 'create_snapshot'
-
1
post 'load_snapshot'
-
1
post 'unload_current_snapshot'
-
-
1
get 'recreate_index'
-
1
get 'search'
-
1
post 'decode_hierarchy_csv'
-
1
post 'decode_location_csv'
-
-
1
get 'sites_info'
-
-
1
resource :import_wizard, only: [] do
-
1
get 'index'
-
1
post 'upload_csv'
-
1
get 'adjustments'
-
1
get 'guess_columns_spec'
-
1
post 'execute'
-
1
post 'validate_sites_with_columns'
-
1
get 'get_visible_sites/:page' => 'import_wizards#get_visible_sites'
-
1
get 'import_in_progress'
-
1
get 'import_finished'
-
1
get 'import_failed'
-
1
get 'job_status'
-
1
get 'cancel_pending_jobs'
-
1
get 'logs'
-
end
-
end
-
-
1
resources :sites do
-
1
get 'root_sites'
-
1
get 'search', :on => :collection
-
1
get 'search_alert_site', :on => :collection
-
-
1
post 'update_property'
-
end
-
-
1
resources :messages, :only => [:index], :path => 'message'
-
1
resources :activities, :only => [:index], :path => 'activity'
-
1
resources :quotas
-
1
resources :channels_accesses
-
-
1
resources :gateways do
-
1
post 'status', :on => :member
-
1
post 'try'
-
end
-
-
1
match 'terms_and_conditions' => redirect("http://instedd.org/terms-of-service/"), :via => :get
-
-
1
namespace :api do
-
1
get 'collections/:id' => 'collections#show',as: :collection
-
1
get 'collections/:id/export_layers' => 'collections#export_layers', as: :export_layers
-
1
get 'collections/:id/download_location_csv' => 'collections#download_location_csv', as: :download_location_csv
-
1
get 'collections/:id/sample_csv' => 'collections#sample_csv',as: :sample_csv
-
1
get 'collections/:id/count' => 'collections#count',as: :count
-
1
get 'collections/:id/geo' => 'collections#geo_json',as: :geojson
-
1
get 'sites/:id' => 'sites#show', as: :site
-
1
get 'activity' => 'activities#index', as: :activity
-
# match 'collections/:id/update_sites_under_collection' => 'collections#update_sites_under_collection', :via => :put
-
# put 'collections/:id/update_sites_under_collection' => 'collections#update_sites_under_collection', as: :collections
-
1
resources :tokens, :only => [:index, :destroy]
-
1
resources :collections do
-
1
get 'sites_by_term'
-
1
member do
-
1
put 'update_sites'
-
1
get 'get_fields'
-
1
get 'get_sites_conflict'
-
1
get 'get_some_sites'
-
end
-
1
resources :fields, only: [:index]
-
1
resources :sites
-
end
-
1
match 'collections/:collection_id/memberships' => 'memberships#create', :via => :post
-
1
match 'collections/:collection_id/memberships' => 'memberships#update', :via => :put
-
1
match 'collections/:collection_id/register_new_member' => 'memberships#register_new_member', :via => :post
-
1
match 'collections/:collection_id/destroy_member' => 'memberships#destroy_member', :via => :delete
-
-
1
devise_scope :user do
-
1
post '/users' => 'registrations#create'
-
1
post '/users/sign_in' => 'sessions#create'
-
1
post '/users/sign_out' => 'sessions#destroy'
-
end
-
-
# v1
-
1
namespace :v1 do
-
1
resources :collections do
-
1
resources :sites, only: [:create,:index,:update,:show] do
-
1
get :visible_layers_for, on: :member
-
end
-
1
resources :memberships, only: [:index] do
-
1
collection do
-
1
get 'search'
-
end
-
end
-
1
resources :fields, only: [:create,:index,:update,:show]
-
1
resources :layer_memberships, only: [:create,:index,:update,:show]
-
1
resources :site_permissions, only: [:create,:index,:update,:show]
-
end
-
1
namespace :admin do
-
1
resources :collections
-
end
-
end
-
-
# v2
-
1
namespace :v2 do
-
1
resources :collections, except: [:update] do
-
1
resources :memberships, only: [:index, :create, :destroy] do
-
1
member do
-
1
post :set_admin
-
1
post :unset_admin
-
end
-
1
collection do
-
1
get 'invitable'
-
end
-
end
-
-
1
resources :layers, except: [:show, :new, :edit] do
-
1
resources :fields, only: [:create]
-
end
-
-
1
resources :fields, only: [:index] do
-
1
collection do
-
1
get 'mapping'
-
end
-
end
-
-
1
member do
-
1
get 'sample_csv', as: :sample_csv
-
1
get 'count', as: :count
-
1
get 'geo', as: :geojson, to: "collections#geo_json"
-
1
post 'sites', to: 'sites#create'
-
1
post 'update_sites', to: 'collections#bulk_update'
-
end
-
end
-
-
1
resources :sites, only: [:show, :destroy, :update] do
-
1
member do
-
1
post :update_property
-
1
post :partial_update
-
end
-
end
-
1
get 'histogram/:field_id', to: 'collections#histogram_by_field', as: :histogram_by_field
-
1
get 'collections/:collection_id/sites/:id/histories' => 'sites#histories', as: :histories
-
1
get 'activity' => 'activities#index', as: :activity
-
1
resources :tokens, :only => [:index, :destroy]
-
end
-
end
-
-
1
namespace :mobile do
-
1
resources :collections do
-
1
resources :sites do
-
1
get :visible_layers_for, on: :member
-
end
-
1
resources :sites_permission
-
1
match 'create_offline_site' => 'sites#create_offline_site', :via => :post
-
end
-
1
match 'collections/:collection_id/sites/:id/update_offline_site' => 'sites#update_offline_site', :via => :put
-
end
-
-
1
scope '/plugin' do
-
1
Plugin.all.each do |plugin|
-
4
scope plugin.name do
-
8
plugin.hooks[:routes].each { |plugin_routes_block| instance_eval &plugin_routes_block }
-
end
-
end
-
end
-
-
1
root :to => 'home#index'
-
-
1
admin_constraint = lambda do |request|
-
request.env['warden'].authenticate? and request.env['warden'].user.is_super_user?
-
end
-
-
1
constraints admin_constraint do
-
1
mount Resque::Server, :at => "/admin/resque"
-
1
match 'analytics' => 'analytics#index', :via => :get
-
1
match 'quota' => 'quota#index', via: :get
-
end
-
-
1
offline = Rack::Offline.configure do
-
1
cache "assets/mobile.js"
-
1
cache "assets/mobile.css"
-
-
1
cache "assets/jquery.mobile-1.3.2.js"
-
1
cache "assets/jquery.mobile-1.3.2.css"
-
-
1
cache "assets/images/ajax-loader.gif"
-
1
cache "assets/images/icons-18-white.png"
-
1
cache "assets/images/icons-36-white.png"
-
-
1
cache "images/add.png"
-
1
cache "images/remove.ico"
-
1
cache "images/favicon.ico"
-
1
network "*"
-
end
-
1
match "/application.manifest" => offline, :via => :get
-
-
# TODO: deprecate later
-
1
match 'collections/:collection_id/fred_api/v1/facilities/:id' => 'fred_api#show_facility', :via => :get
-
1
match 'collections/:collection_id/fred_api/v1/facilities' => 'fred_api#facilities', :via => :get
-
1
match 'collections/:collection_id/fred_api/v1/facilities/:id' => 'fred_api#delete_facility', :via => :delete
-
1
match 'collections/:collection_id/fred_api/v1/facilities' => 'fred_api#create_facility', :via => :post
-
1
match 'collections/:collection_id/fred_api/v1/facilities/:id(.:format)' => 'fred_api#update_facility', :via => :put
-
-
-
end
-
1
module ActiveRecordTelemetry
-
-
1
extend ActiveSupport::Concern
-
-
1
def touch_user_lifespan
-
713
Telemetry::Lifespan.touch_user(self.user)
-
end
-
-
1
def touch_collection_lifespan
-
3967
Telemetry::Lifespan.touch_collection(self.collection)
-
end
-
-
1
def touch_membership_lifespan
-
50
Telemetry::Lifespan.touch_collection(self.membership.try(:collection))
-
50
Telemetry::Lifespan.touch_user(self.membership.try(:user))
-
end
-
-
end
-
-
1
ActiveRecord::Base.send(:include, ActiveRecordTelemetry)
-
# Autogenerated from a Treetop grammar. Edits may be lost.
-
-
-
1
module Command
-
1
include Treetop::Runtime
-
-
1
def root
-
@root ||= :dyrm_command
-
end
-
-
1
module DyrmCommand0
-
1
def dyrm
-
elements[0]
-
end
-
-
1
def space
-
elements[1]
-
end
-
-
1
def command
-
elements[2]
-
end
-
end
-
-
1
def _nt_dyrm_command
-
start_index = index
-
if node_cache[:dyrm_command].has_key?(index)
-
cached = node_cache[:dyrm_command][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
r1 = _nt_dyrm
-
s0 << r1
-
if r1
-
r2 = _nt_space
-
s0 << r2
-
if r2
-
r3 = _nt_command
-
s0 << r3
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
r0.extend(DyrmCommand0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:dyrm_command][start_index] = r0
-
-
r0
-
end
-
-
1
module Dyrm0
-
end
-
-
1
def _nt_dyrm
-
start_index = index
-
if node_cache[:dyrm].has_key?(index)
-
cached = node_cache[:dyrm][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
i1 = index
-
if has_terminal?('d', false, index)
-
r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('d')
-
r2 = nil
-
end
-
if r2
-
r1 = r2
-
else
-
if has_terminal?('D', false, index)
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('D')
-
r3 = nil
-
end
-
if r3
-
r1 = r3
-
else
-
@index = i1
-
r1 = nil
-
end
-
end
-
s0 << r1
-
if r1
-
i4 = index
-
if has_terminal?('y', false, index)
-
r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('y')
-
r5 = nil
-
end
-
if r5
-
r4 = r5
-
else
-
if has_terminal?('Y', false, index)
-
r6 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('Y')
-
r6 = nil
-
end
-
if r6
-
r4 = r6
-
else
-
@index = i4
-
r4 = nil
-
end
-
end
-
s0 << r4
-
if r4
-
i7 = index
-
if has_terminal?('r', false, index)
-
r8 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('r')
-
r8 = nil
-
end
-
if r8
-
r7 = r8
-
else
-
if has_terminal?('R', false, index)
-
r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('R')
-
r9 = nil
-
end
-
if r9
-
r7 = r9
-
else
-
@index = i7
-
r7 = nil
-
end
-
end
-
s0 << r7
-
if r7
-
i10 = index
-
if has_terminal?('m', false, index)
-
r11 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('m')
-
r11 = nil
-
end
-
if r11
-
r10 = r11
-
else
-
if has_terminal?('M', false, index)
-
r12 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('M')
-
r12 = nil
-
end
-
if r12
-
r10 = r12
-
else
-
@index = i10
-
r10 = nil
-
end
-
end
-
s0 << r10
-
end
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
r0.extend(Dyrm0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:dyrm][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_command
-
start_index = index
-
if node_cache[:command].has_key?(index)
-
cached = node_cache[:command][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0 = index
-
r1 = _nt_query_command
-
if r1
-
r0 = r1
-
else
-
r2 = _nt_update_command
-
if r2
-
r0 = r2
-
else
-
r3 = _nt_add_command
-
if r3
-
r0 = r3
-
else
-
@index = i0
-
r0 = nil
-
end
-
end
-
end
-
-
node_cache[:command][start_index] = r0
-
-
r0
-
end
-
-
1
module QueryCommand0
-
1
def space1
-
elements[1]
-
end
-
-
1
def collection_id
-
elements[2]
-
end
-
-
1
def space2
-
elements[3]
-
end
-
-
1
def conditional_expression
-
elements[4]
-
end
-
-
1
def new_line
-
elements[6]
-
end
-
end
-
-
1
def _nt_query_command
-
start_index = index
-
if node_cache[:query_command].has_key?(index)
-
cached = node_cache[:query_command][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
i1 = index
-
if has_terminal?('q', false, index)
-
r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('q')
-
r2 = nil
-
end
-
if r2
-
r1 = r2
-
else
-
if has_terminal?('Q', false, index)
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('Q')
-
r3 = nil
-
end
-
if r3
-
r1 = r3
-
else
-
@index = i1
-
r1 = nil
-
end
-
end
-
s0 << r1
-
if r1
-
r4 = _nt_space
-
s0 << r4
-
if r4
-
r5 = _nt_number
-
s0 << r5
-
if r5
-
r6 = _nt_space
-
s0 << r6
-
if r6
-
r7 = _nt_conditional_expression
-
s0 << r7
-
if r7
-
r9 = _nt_space
-
if r9
-
r8 = r9
-
else
-
r8 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r8
-
if r8
-
r10 = _nt_new_line
-
s0 << r10
-
end
-
end
-
end
-
end
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(QueryCommandNode,input, i0...index, s0)
-
r0.extend(QueryCommand0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:query_command][start_index] = r0
-
-
r0
-
end
-
-
1
module UpdateCommand0
-
1
def space1
-
elements[1]
-
end
-
-
1
def resource_id
-
elements[2]
-
end
-
-
1
def space2
-
elements[3]
-
end
-
-
1
def property_list
-
elements[4]
-
end
-
-
1
def new_line
-
elements[7]
-
end
-
end
-
-
1
def _nt_update_command
-
start_index = index
-
if node_cache[:update_command].has_key?(index)
-
cached = node_cache[:update_command][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
i1 = index
-
if has_terminal?('u', false, index)
-
r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('u')
-
r2 = nil
-
end
-
if r2
-
r1 = r2
-
else
-
if has_terminal?('U', false, index)
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('U')
-
r3 = nil
-
end
-
if r3
-
r1 = r3
-
else
-
@index = i1
-
r1 = nil
-
end
-
end
-
s0 << r1
-
if r1
-
r4 = _nt_space
-
s0 << r4
-
if r4
-
r5 = _nt_resource
-
s0 << r5
-
if r5
-
r6 = _nt_space
-
s0 << r6
-
if r6
-
r7 = _nt_property_list
-
s0 << r7
-
if r7
-
r9 = _nt_space
-
if r9
-
r8 = r9
-
else
-
r8 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r8
-
if r8
-
s10, i10 = [], index
-
loop do
-
r11 = _nt_comma
-
if r11
-
s10 << r11
-
else
-
break
-
end
-
end
-
r10 = instantiate_node(SyntaxNode,input, i10...index, s10)
-
s0 << r10
-
if r10
-
r12 = _nt_new_line
-
s0 << r12
-
end
-
end
-
end
-
end
-
end
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(UpdateCommandNode,input, i0...index, s0)
-
r0.extend(UpdateCommand0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:update_command][start_index] = r0
-
-
r0
-
end
-
-
1
module AddCommand0
-
1
def space
-
elements[1]
-
end
-
-
1
def collection_id
-
elements[2]
-
end
-
-
1
def property_list
-
elements[3]
-
end
-
-
1
def new_line
-
elements[6]
-
end
-
end
-
-
1
def _nt_add_command
-
start_index = index
-
if node_cache[:add_command].has_key?(index)
-
cached = node_cache[:add_command][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
i1 = index
-
if has_terminal?('a', false, index)
-
r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('a')
-
r2 = nil
-
end
-
if r2
-
r1 = r2
-
else
-
if has_terminal?('A', false, index)
-
r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('A')
-
r3 = nil
-
end
-
if r3
-
r1 = r3
-
else
-
@index = i1
-
r1 = nil
-
end
-
end
-
s0 << r1
-
if r1
-
r4 = _nt_space
-
s0 << r4
-
if r4
-
r6 = _nt_optional_colelction_id
-
if r6
-
r5 = r6
-
else
-
r5 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r5
-
if r5
-
r7 = _nt_property_list
-
s0 << r7
-
if r7
-
r9 = _nt_space
-
if r9
-
r8 = r9
-
else
-
r8 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r8
-
if r8
-
s10, i10 = [], index
-
loop do
-
r11 = _nt_comma
-
if r11
-
s10 << r11
-
else
-
break
-
end
-
end
-
r10 = instantiate_node(SyntaxNode,input, i10...index, s10)
-
s0 << r10
-
if r10
-
r12 = _nt_new_line
-
s0 << r12
-
end
-
end
-
end
-
end
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(AddCommandNode,input, i0...index, s0)
-
r0.extend(AddCommand0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:add_command][start_index] = r0
-
-
r0
-
end
-
-
1
module PropertyList0
-
1
def assignment_expression
-
elements[0]
-
end
-
-
1
def next
-
elements[4]
-
end
-
end
-
-
1
def _nt_property_list
-
start_index = index
-
if node_cache[:property_list].has_key?(index)
-
cached = node_cache[:property_list][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0 = index
-
i1, s1 = index, []
-
r2 = _nt_assignment_expression
-
s1 << r2
-
if r2
-
r4 = _nt_space
-
if r4
-
r3 = r4
-
else
-
r3 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s1 << r3
-
if r3
-
if has_terminal?(',', false, index)
-
r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure(',')
-
r5 = nil
-
end
-
s1 << r5
-
if r5
-
r7 = _nt_space
-
if r7
-
r6 = r7
-
else
-
r6 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s1 << r6
-
if r6
-
r8 = _nt_property_list
-
s1 << r8
-
end
-
end
-
end
-
end
-
if s1.last
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
-
r1.extend(PropertyList0)
-
else
-
@index = i1
-
r1 = nil
-
end
-
if r1
-
r0 = r1
-
else
-
r9 = _nt_assignment_expression
-
if r9
-
r0 = r9
-
else
-
@index = i0
-
r0 = nil
-
end
-
end
-
-
node_cache[:property_list][start_index] = r0
-
-
r0
-
end
-
-
1
module AssignmentExpression0
-
1
def name
-
elements[0]
-
end
-
-
1
def value
-
elements[4]
-
end
-
end
-
-
1
def _nt_assignment_expression
-
start_index = index
-
if node_cache[:assignment_expression].has_key?(index)
-
cached = node_cache[:assignment_expression][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
r1 = _nt_property
-
s0 << r1
-
if r1
-
r3 = _nt_space
-
if r3
-
r2 = r3
-
else
-
r2 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r2
-
if r2
-
if has_terminal?('=', false, index)
-
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('=')
-
r4 = nil
-
end
-
s0 << r4
-
if r4
-
r6 = _nt_space
-
if r6
-
r5 = r6
-
else
-
r5 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r5
-
if r5
-
r7 = _nt_value
-
s0 << r7
-
end
-
end
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(AssignmentExpressionNode,input, i0...index, s0)
-
r0.extend(AssignmentExpression0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:assignment_expression][start_index] = r0
-
-
r0
-
end
-
-
1
module ConditionalExpression0
-
1
def name
-
elements[0]
-
end
-
-
1
def operator
-
elements[2]
-
end
-
-
1
def value
-
elements[4]
-
end
-
end
-
-
1
def _nt_conditional_expression
-
start_index = index
-
if node_cache[:conditional_expression].has_key?(index)
-
cached = node_cache[:conditional_expression][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
r1 = _nt_property
-
s0 << r1
-
if r1
-
r3 = _nt_space
-
if r3
-
r2 = r3
-
else
-
r2 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r2
-
if r2
-
r4 = _nt_comparison_operator
-
s0 << r4
-
if r4
-
r6 = _nt_space
-
if r6
-
r5 = r6
-
else
-
r5 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r5
-
if r5
-
r7 = _nt_value
-
s0 << r7
-
end
-
end
-
end
-
end
-
if s0.last
-
r0 = instantiate_node(ConditionalExpressionNode,input, i0...index, s0)
-
r0.extend(ConditionalExpression0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:conditional_expression][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_resource
-
start_index = index
-
if node_cache[:resource].has_key?(index)
-
cached = node_cache[:resource][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
s0, i0 = [], index
-
loop do
-
r1 = _nt_alpha_numeric
-
if r1
-
s0 << r1
-
else
-
break
-
end
-
end
-
if s0.empty?
-
@index = i0
-
r0 = nil
-
else
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
end
-
-
node_cache[:resource][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_property
-
start_index = index
-
if node_cache[:property].has_key?(index)
-
cached = node_cache[:property][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
r0 = _nt_phrase
-
-
node_cache[:property][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_value
-
start_index = index
-
if node_cache[:value].has_key?(index)
-
cached = node_cache[:value][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0 = index
-
r1 = _nt_number
-
if r1
-
r0 = r1
-
else
-
r2 = _nt_string
-
if r2
-
r0 = r2
-
else
-
@index = i0
-
r0 = nil
-
end
-
end
-
-
node_cache[:value][start_index] = r0
-
-
r0
-
end
-
-
1
module OptionalColelctionId0
-
1
def space
-
elements[1]
-
end
-
end
-
-
1
def _nt_optional_colelction_id
-
start_index = index
-
if node_cache[:optional_colelction_id].has_key?(index)
-
cached = node_cache[:optional_colelction_id][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
s1, i1 = [], index
-
loop do
-
r2 = _nt_digit
-
if r2
-
s1 << r2
-
else
-
break
-
end
-
end
-
if s1.empty?
-
@index = i1
-
r1 = nil
-
else
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
-
end
-
s0 << r1
-
if r1
-
r3 = _nt_space
-
s0 << r3
-
end
-
if s0.last
-
r0 = instantiate_node(CollectionNode,input, i0...index, s0)
-
r0.extend(OptionalColelctionId0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:optional_colelction_id][start_index] = r0
-
-
r0
-
end
-
-
1
module String0
-
1
def phrase
-
elements[0]
-
end
-
-
end
-
-
1
def _nt_string
-
start_index = index
-
if node_cache[:string].has_key?(index)
-
cached = node_cache[:string][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
r1 = _nt_phrase
-
s0 << r1
-
if r1
-
r3 = _nt_space
-
if r3
-
r2 = r3
-
else
-
r2 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r2
-
end
-
if s0.last
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
r0.extend(String0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:string][start_index] = r0
-
-
r0
-
end
-
-
1
module Phrase0
-
1
def word
-
elements[0]
-
end
-
-
1
def space
-
elements[1]
-
end
-
-
1
def phrase
-
elements[2]
-
end
-
end
-
-
1
def _nt_phrase
-
start_index = index
-
if node_cache[:phrase].has_key?(index)
-
cached = node_cache[:phrase][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0 = index
-
i1, s1 = index, []
-
r2 = _nt_word
-
s1 << r2
-
if r2
-
r3 = _nt_space
-
s1 << r3
-
if r3
-
r4 = _nt_phrase
-
s1 << r4
-
end
-
end
-
if s1.last
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
-
r1.extend(Phrase0)
-
else
-
@index = i1
-
r1 = nil
-
end
-
if r1
-
r0 = r1
-
else
-
r5 = _nt_word
-
if r5
-
r0 = r5
-
else
-
@index = i0
-
r0 = nil
-
end
-
end
-
-
node_cache[:phrase][start_index] = r0
-
-
r0
-
end
-
-
1
module Number0
-
end
-
-
1
def _nt_number
-
start_index = index
-
if node_cache[:number].has_key?(index)
-
cached = node_cache[:number][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
s1, i1 = [], index
-
loop do
-
r2 = _nt_digit
-
if r2
-
s1 << r2
-
else
-
break
-
end
-
end
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
-
s0 << r1
-
if r1
-
i3 = index
-
r4 = _nt_word
-
if r4
-
r3 = nil
-
else
-
@index = i3
-
r3 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r3
-
end
-
if s0.last
-
r0 = instantiate_node(NumberNode,input, i0...index, s0)
-
r0.extend(Number0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:number][start_index] = r0
-
-
r0
-
end
-
-
1
module Word0
-
end
-
-
1
def _nt_word
-
start_index = index
-
if node_cache[:word].has_key?(index)
-
cached = node_cache[:word][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0 = index
-
i1, s1 = index, []
-
s2, i2 = [], index
-
loop do
-
r3 = _nt_character
-
if r3
-
s2 << r3
-
else
-
break
-
end
-
end
-
if s2.empty?
-
@index = i2
-
r2 = nil
-
else
-
r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
-
end
-
s1 << r2
-
if r2
-
s4, i4 = [], index
-
loop do
-
r5 = _nt_symbol
-
if r5
-
s4 << r5
-
else
-
break
-
end
-
end
-
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
-
s1 << r4
-
if r4
-
s6, i6 = [], index
-
loop do
-
r7 = _nt_character
-
if r7
-
s6 << r7
-
else
-
break
-
end
-
end
-
r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
-
s1 << r6
-
end
-
end
-
if s1.last
-
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
-
r1.extend(Word0)
-
else
-
@index = i1
-
r1 = nil
-
end
-
if r1
-
r0 = r1
-
else
-
r8 = _nt_symbol
-
if r8
-
r0 = r8
-
else
-
@index = i0
-
r0 = nil
-
end
-
end
-
-
node_cache[:word][start_index] = r0
-
-
r0
-
end
-
-
1
module Unicode0
-
end
-
-
1
def _nt_unicode
-
start_index = index
-
if node_cache[:unicode].has_key?(index)
-
cached = node_cache[:unicode][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
if index < input_length
-
r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure("any character")
-
r1 = nil
-
end
-
s0 << r1
-
if r1
-
i2 = index
-
r3 = lambda { |s| s.first.text_value.ascii_only? }.call(s0)
-
if r3
-
r2 = nil
-
else
-
@index = i2
-
r2 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r2
-
end
-
if s0.last
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
r0.extend(Unicode0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:unicode][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_character
-
start_index = index
-
if node_cache[:character].has_key?(index)
-
cached = node_cache[:character][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0 = index
-
r1 = _nt_unicode
-
if r1
-
r0 = r1
-
else
-
r2 = _nt_alpha_numeric
-
if r2
-
r0 = r2
-
else
-
@index = i0
-
r0 = nil
-
end
-
end
-
-
node_cache[:character][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_digit
-
start_index = index
-
if node_cache[:digit].has_key?(index)
-
cached = node_cache[:digit][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
if has_terminal?('\G[\\d]', true, index)
-
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
r0 = nil
-
end
-
-
node_cache[:digit][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_alpha_numeric
-
start_index = index
-
if node_cache[:alpha_numeric].has_key?(index)
-
cached = node_cache[:alpha_numeric][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
if has_terminal?('\G[\\w]', true, index)
-
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
r0 = nil
-
end
-
-
node_cache[:alpha_numeric][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_symbol
-
start_index = index
-
if node_cache[:symbol].has_key?(index)
-
cached = node_cache[:symbol][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
if has_terminal?('\G[\\.\\?:;\\-_+\\!@\\$%&*|\\\\/(){}\\[\\]"\']', true, index)
-
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
r0 = nil
-
end
-
-
node_cache[:symbol][start_index] = r0
-
-
r0
-
end
-
-
1
module ComparisonOperator0
-
end
-
-
1
def _nt_comparison_operator
-
start_index = index
-
if node_cache[:comparison_operator].has_key?(index)
-
cached = node_cache[:comparison_operator][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
i0, s0 = index, []
-
if has_terminal?('\G[\\<\\>]', true, index)
-
r2 = true
-
@index += 1
-
else
-
r2 = nil
-
end
-
if r2
-
r1 = r2
-
else
-
r1 = instantiate_node(SyntaxNode,input, index...index)
-
end
-
s0 << r1
-
if r1
-
s3, i3 = [], index
-
loop do
-
if has_terminal?('=', false, index)
-
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure('=')
-
r4 = nil
-
end
-
if r4
-
s3 << r4
-
else
-
break
-
end
-
if s3.size == 2
-
break
-
end
-
end
-
r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
-
s0 << r3
-
end
-
if s0.last
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
r0.extend(ComparisonOperator0)
-
else
-
@index = i0
-
r0 = nil
-
end
-
-
node_cache[:comparison_operator][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_space
-
start_index = index
-
if node_cache[:space].has_key?(index)
-
cached = node_cache[:space][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
s0, i0 = [], index
-
loop do
-
if has_terminal?('\G[\\s]', true, index)
-
r1 = true
-
@index += 1
-
else
-
r1 = nil
-
end
-
if r1
-
s0 << r1
-
else
-
break
-
end
-
end
-
if s0.empty?
-
@index = i0
-
r0 = nil
-
else
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
end
-
-
node_cache[:space][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_comma
-
start_index = index
-
if node_cache[:comma].has_key?(index)
-
cached = node_cache[:comma][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
if has_terminal?(',', false, index)
-
r0 = instantiate_node(SyntaxNode,input, index...(index + 1))
-
@index += 1
-
else
-
terminal_parse_failure(',')
-
r0 = nil
-
end
-
-
node_cache[:comma][start_index] = r0
-
-
r0
-
end
-
-
1
def _nt_new_line
-
start_index = index
-
if node_cache[:new_line].has_key?(index)
-
cached = node_cache[:new_line][index]
-
if cached
-
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
-
@index = cached.interval.end
-
end
-
return cached
-
end
-
-
s0, i0 = [], index
-
loop do
-
if has_terminal?('\G[\\n\\r]', true, index)
-
r1 = true
-
@index += 1
-
else
-
r1 = nil
-
end
-
if r1
-
s0 << r1
-
else
-
break
-
end
-
end
-
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
-
-
node_cache[:new_line][start_index] = r0
-
-
r0
-
end
-
-
end
-
-
1
class CommandParser < Treetop::Runtime::CompiledParser
-
1
include Command
-
end
-
-
1
class ExecVisitor < Visitor
-
1
MSG = {
-
:query_not_match => "No result. Your query did not match.",
-
:update_successfully => "Data has been successfully updated.",
-
:no_rights_not_update => "You have no access rights to update. Please contact the collection's owner for more information.",
-
:can_not_query => "You have no access rights to view. Please contact the collection's owner for more information.",
-
:can_not_use_gateway => "You cannot use this channel for viewing or updating this collection. Please contact the collection's owner for more information.",
-
:can_not_update => "Can not update site ",
-
:can_not_add => "Can not create site ",
-
:added_successfully => "Site has been successfully added.",
-
:name_is_required => "Site name is required.",
-
:can_not_find_site => "Can't find site with ID=",
-
:can_not_add_site => "You don't have permission to add site."
-
}
-
-
1
attr_accessor :context
-
1
def initialize(context={})
-
7
self.context = context
-
end
-
-
1
def visit_query_command(node)
-
9
if collection = Collection.find_by_id(node.collection_id.value)
-
#raise MSG[:can_not_use_gateway] unless can_use_gateway?(collection)
-
9
raise MSG[:can_not_query] unless can_view?(node.conditional_expression.to_options, node.sender, collection)
-
7
if reply = collection.query_sites(node.conditional_expression.to_options)
-
6
reply.empty? ? MSG[:query_not_match] : reply
-
end
-
end
-
end
-
-
1
def visit_update_command(node)
-
10
id = node.resource_id.text_value
-
10
if site = Site.find_by_id_with_prefix(id)
-
#raise MSG[:can_not_use_gateway] unless can_use_gateway?(site.collection)
-
8
raise MSG[:no_rights_not_update] unless can_update?(node.property_list, node.sender, site)
-
7
update site, node.property_list, node.sender
-
7
MSG[:update_successfully]
-
else
-
2
raise MSG[:can_not_find_site] + id if site.nil?
-
end
-
end
-
-
1
def visit_add_command(node)
-
7
if node.collection_id.text_value.empty?
-
4
collections = node.sender.collections
-
4
if collections.length != 1
-
2
return "Collection id is needed in your message."
-
else
-
2
collection = collections.first
-
end
-
else
-
3
return MSG[:can_not_add_site] if node.sender.nil? or not node.sender.can_add?(node.collection_id.value)
-
3
collection = Collection.find node.collection_id.value
-
end
-
-
5
if collection
-
5
key_value_properties = node_to_properties(node.property_list)
-
5
site = node_to_site key_value_properties
-
5
if collection.is_visible_name == true && (not site.keys.include?('name'))
-
1
return MSG[:name_is_required]
-
end
-
-
4
properties = node_to_site_properties key_value_properties,collection.id
-
4
if properties["not_exist"]
-
if properties["not_exist"].length > 1
-
return 'Field codes: ' + properties["not_exist"].join(',') + ' are not exist.'
-
else
-
return 'Field code: ' + properties["not_exist"].join(',') + ' is not exist.'
-
end
-
end
-
4
site["properties"] = node_to_site_properties key_value_properties,collection.id
-
4
site["user"] = node.sender
-
4
new_site = collection.sites.new site
-
4
if new_site.valid?
-
4
new_site.save!
-
4
MSG[:added_successfully]
-
else
-
errors = []
-
new_site.errors.messages[:properties].each do |e|
-
e.each do |key, value|
-
errors.push "- " + value
-
end
-
end
-
MSG[:can_not_add] + "\n" + errors.join("\n")
-
end
-
else
-
MSG[:can_not_add]
-
end
-
end
-
-
1
def can_use_gateway?(colleciton)
-
gateway = Gateway.find_by_nuntium_name(self.context[:channel])
-
gateway.nil? || gateway.allows_layer?(layer)
-
end
-
-
1
def can_view?(option, sender, collection)
-
10
sender && sender.can_view?(collection, option[:code])
-
end
-
-
1
def can_update?(node, sender, site)
-
8
properties = node_to_properties node
-
8
sender && sender.can_update?(site, properties)
-
end
-
-
1
def update(site, node, sender)
-
7
properties = node_to_properties(node)
-
7
update_properties site, sender, properties
-
end
-
-
1
def update_properties(site, user, props)
-
5
site.user = user
-
5
props.each do |p|
-
6
code = p[:code]
-
6
if code != "name"
-
6
field =Field.where("code=? and collection_id=?", p.values[0], site.collection_id).first
-
6
site.properties[field.es_code] = to_supported_value(field, p.values[1])
-
else
-
site[code] = p.values[1]
-
end
-
end
-
5
if site.valid?
-
5
site.save!
-
else
-
errors = []
-
site.errors.messages[:properties].each do |e|
-
e.each do |key, value|
-
errors.push "- " + value
-
end
-
end
-
raise MSG[:can_not_update] + "\n" + errors.join("\n")
-
end
-
end
-
-
1
def node_to_properties(node)
-
23
properties = []
-
23
until node and node.kind_of? AssignmentExpressionNode
-
25
properties << node.assignment_expression.to_options
-
25
node = node.next
-
end
-
23
properties << node.to_options
-
end
-
-
1
def get_field_id(field_code, collection_id)
-
8
field = Field.where("code=? and collection_id=?",field_code, collection_id).first
-
8
if field
-
8
field.id
-
else
-
nil
-
end
-
end
-
-
1
def node_to_site_properties(key_value_properties, collection_id)
-
9
properties = {}
-
9
key_value_properties.each { |property|
-
33
code = property[:code]
-
33
if code != 'name' and code != 'lat' and code != 'lng'
-
8
id = get_field_id(code,collection_id)
-
8
if id
-
8
field =Field.find_by_id id
-
8
properties[id.to_s] = to_supported_value(field, property[:value])
-
else
-
properties['not_exist'] = [] if properties['not_exist'].nil?
-
properties['not_exist'].push code
-
end
-
end
-
}
-
9
properties
-
end
-
-
1
def node_to_site(key_value_properties)
-
6
site = {}
-
6
key_value_properties.each { |property|
-
22
code = property[:code]
-
22
site[code] = property[:value] if code == 'name' or code == 'lat' or code == 'lng'
-
}
-
6
site
-
end
-
-
1
def to_supported_value(field, value)
-
14
case field.kind
-
when "yes_no"
-
return not(["n", "N", "no", "NO", "No", "nO", "0"].include? value)
-
when "select_one"
-
field.config["options"].each do |op|
-
return op["id"] if (op["code"] == value || op["label"] == value)
-
end
-
when "select_many"
-
3
many_value = value.split('&')
-
3
result = []
-
3
many_value.each do |v|
-
6
field.config["options"].each do |op|
-
12
if (op["code"] == v || op["label"] == v)
-
6
result.push(op["id"])
-
end
-
end
-
end
-
3
if result.length > 0
-
3
return result
-
else
-
nil
-
end
-
else
-
11
return value
-
end
-
end
-
end
-
1
class FeedbackVisitor < Visitor
-
1
def visit_query_command(node)
-
# if node.reply_text
-
# response.headers['X-GeoChat-Action'] = 'reply'
-
# render :text => node.reply_text
-
# else
-
# response.headers['X-GeoChat-Action'] = 'stop'
-
# head :ok
-
# end
-
end
-
-
1
def visit_update_command(node)
-
msg = <<-MSG
-
You send an sms update for:
-
- Resource: "#{node.resource_id.value}"
-
- Properties:
-
MSG
-
current = node.property_list
-
until current.kind_of? AssignmentExpressionNode
-
assignment_expression = current.assignment_expression
-
msg << " - " << assignment_expression.name.text_value << "=" << assignment_expression.value.text_value << "\n"
-
current = current.next
-
end
-
msg << " - " << current.name.text_value << "=" << current.value.text_value << "\n"
-
-
node.reply_text = msg
-
end
-
end
-
1
class CommandNode < Treetop::Runtime::SyntaxNode
-
1
attr_accessor :sender
-
-
1
def set_reply_text(value)
-
@reply_text = value
-
end
-
-
1
def reply_text
-
@reply_text
-
end
-
end
-
-
1
class QueryCommandNode < CommandNode
-
# :condition
-
1
def accept(visitor)
-
visitor.visit_query_command self
-
end
-
end
-
-
1
class UpdateCommandNode < CommandNode
-
# :resource_id
-
# :property_list
-
1
def accept(visitor)
-
3
visitor.visit_update_command self
-
end
-
end
-
-
1
class AddCommandNode < CommandNode
-
1
def accept(visitor)
-
visitor.visit_add_command self
-
end
-
end
-
-
1
class ConditionalExpressionNode < Treetop::Runtime::SyntaxNode
-
# :string
-
# :comparison_operator
-
# :value
-
1
def to_options
-
{
-
:code => self.name.text_value,
-
:operator => self.operator.text_value,
-
:value => self.value.text_value
-
16
}
-
end
-
end
-
-
1
class AssignmentExpressionNode < Treetop::Runtime::SyntaxNode
-
# :string
-
# :value
-
1
def to_options
-
{
-
:code => self.name.text_value,
-
:value => self.value.text_value
-
48
}
-
end
-
end
-
-
1
class NumberNode < Treetop::Runtime::SyntaxNode
-
1
def value
-
29
text_value.to_i
-
end
-
end
-
-
1
class CollectionNode < Treetop::Runtime::SyntaxNode
-
1
def value
-
7
text_value.to_i
-
end
-
end
-
1
class Visitor
-
-
# default fallback - visit_query_command
-
1
def visit_query_command(node); end
-
-
# default fallback - visit_update_command
-
1
def visit_update_command(node); end
-
-
1
def visit_add_command(node); end
-
-
end
-
1
require 'treetop'
-
-
1
require File.join(File.dirname(__FILE__), 'treetop/command')
-
1
require File.join(File.dirname(__FILE__), 'treetop/nodes')
-
1
require File.join(File.dirname(__FILE__), 'treetop/visitor')
-
1
require File.join(File.dirname(__FILE__), 'treetop/exec_visitor')
-
1
require File.join(File.dirname(__FILE__), 'treetop/feedback_visitor')
-
1
class ThresholdsController < ApplicationController
-
1
before_filter :authenticate_user!, :except => [:index]
-
-
1
before_filter :fix_conditions, only: [:create, :update]
-
-
1
def index
-
if params[:collection_id]
-
respond_to do |format|
-
format.html do
-
show_collection_breadcrumb
-
add_breadcrumb I18n.t('views.collections.index.properties'), collection_path(collection)
-
add_breadcrumb I18n.t('views.plugins.alerts.thresholds'), collection_thresholds_path(collection)
-
end
-
format.json { render json: thresholds, :root => false }
-
end
-
else
-
if current_user
-
thresholds = Threshold.get_thresholds_by_user current_user
-
else
-
thresholds = Threshold.get_thresholds_with_public_collection
-
end
-
-
respond_to do |format|
-
format.json { render json: thresholds, :root => false }
-
end
-
end
-
end
-
-
1
def create
-
params[:threshold][:sites] = params[:threshold][:sites].values.map{|site| site["id"]} if params[:threshold][:sites]
-
params[:threshold][:email_notification] = {} unless params[:threshold][:email_notification] # email not selected
-
params[:threshold][:phone_notification] = {} unless params[:threshold][:phone_notification] # phone not selected
-
threshold = thresholds.new threshold_params
-
threshold.sites = Site.get_id_and_name params[:threshold][:sites] if params[:threshold][:sites]#select only id and name
-
threshold.strongly_type_conditions
-
threshold.save!
-
# collection.recreate_index
-
Resque.enqueue IndexRecreateTask, collection.id
-
render json: threshold
-
end
-
-
1
def set_order
-
threshold.update_attribute :ord, params[:ord]
-
Resque.enqueue IndexRecreateTask, collection.id
-
render json: threshold
-
end
-
-
1
def update
-
params[:threshold][:email_notification] = {} unless params[:threshold][:email_notification] # email not selected
-
params[:threshold][:phone_notification] = {} unless params[:threshold][:phone_notification] # phone not selected
-
params[:threshold][:sites] = params[:threshold][:sites].values.map{|site| site["id"]} if params[:threshold][:sites]
-
threshold.strongly_type_conditions
-
threshold.update_attributes! params[:threshold].except(:sites)
-
if params[:threshold][:is_all_site] == "false" && params[:threshold][:sites]
-
threshold.sites = Site.get_id_and_name params[:threshold][:sites]
-
threshold.save
-
else
-
threshold.sites = nil
-
threshold.save
-
end
-
-
# collection.recreate_index
-
Resque.enqueue IndexRecreateTask, collection.id
-
render json: threshold
-
end
-
-
1
def destroy
-
threshold.destroy
-
# collection.recreate_index
-
Resque.enqueue IndexRecreateTask, collection.id
-
-
render json: threshold
-
end
-
-
1
private
-
1
def threshold_params
-
params.require(:threshold).permit(:name, :color, :is_all_site, :is_all_condition, :is_notify, :ord , :message_notification, :email_notification => {:members=>[]} , :phone_notification =>{:members=>[]}, :conditions => [:field, :op, :value, :type, :kind])
-
end
-
-
1
def fix_conditions
-
params[:threshold][:conditions] = params[:threshold][:conditions].values
-
end
-
end
-
1
class Field::EmailField < Field
-
1
def value_type_description
-
3
"email addresses"
-
end
-
-
1
def value_hint
-
3
"Example of valid email: myemail@resourcemap.com."
-
end
-
-
1
def valid_value?(email_value, site=nil)
-
18
check_email_format(email_value)
-
end
-
-
1
private
-
-
1
def check_email_format(value)
-
18
regex = Regexp.new('^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6})$')
-
18
if value.match(regex).nil?
-
7
raise "Invalid email address in field #{code}"
-
end
-
11
true
-
end
-
-
end
-
1
class Field::PhoneField < Field
-
-
end
-
1
module Site::AlertConcerns
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
698
before_index :set_alert, if: ->(site) { site.collection.alerts_plugin_enabled? }
-
end
-
-
1
def set_alert
-
697
alert = collection.thresholds_test self unless self.is_a? SiteHistory
-
697
if alert != nil
-
extended_properties[:alert] = true
-
extended_properties[:color] = alert.color
-
extended_properties[:ord] = alert.ord
-
#if alert.is_notify
-
# phone_numbers = notification_numbers alert
-
# emails = notification_emails alert
-
# message_notification = alert.message_notification.render_template_string(get_template_value_hash)
-
-
# to be refactoring
-
# active_gateway = collection.active_gateway
-
# suggested_channel = active_gateway.nil?? Channel.default_nuntium_name : active_gateway.nuntium_channel_name
-
-
# Resque.enqueue SmsTask, phone_numbers, message_notification, suggested_channel, collection.id unless phone_numbers.empty?
-
# Resque.enqueue EmailTask, emails, message_notification, "[ResourceMap] Alert Notification" unless emails.empty?
-
#end
-
else
-
697
extended_properties[:alert] = false
-
end
-
697
true
-
end
-
-
1
def notification_numbers(alert)
-
phone_numbers = collection.users.where(id: alert.phone_notification[:members]).map(&:phone_number).reject &:blank?
-
phone_numbers |= alert.phone_notification[:fields].to_a.map{|field| properties[field] }.reject &:blank?
-
users = alert.phone_notification[:users].to_a.map{|field| properties[field] }.reject(&:blank?)
-
phone_numbers |= User.where(email: users).map(&:phone_number).reject(&:blank?)
-
end
-
-
1
def notification_emails(alert)
-
emails = collection.users.where(id: alert.email_notification[:members]).map(&:email).reject &:blank?
-
emails |= alert.email_notification[:fields].to_a.map{|field| properties[field] }.reject &:blank?
-
emails |= alert.email_notification[:users].to_a.map{|field| properties[field] }.reject(&:blank?)
-
end
-
end
-
1
module Site::TemplateConcerns
-
1
extend ActiveSupport::Concern
-
-
1
def get_template_value_hash
-
template_value = human_properties
-
template_value["Site Name"] = self.name
-
template_value
-
end
-
end
-
1
class Threshold < ActiveRecord::Base
-
1
belongs_to :collection
-
-
1
validates :collection, :presence => true
-
1
validates :ord, :presence => true
-
1
validates :color, :presence => true
-
-
1
serialize :conditions, Array
-
1
serialize :phone_notification
-
1
serialize :email_notification
-
1
serialize :sites, Array
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
def strongly_type_conditions
-
fields = collection.fields.index_by(&:es_code)
-
self.conditions.each_with_index do |hash, i|
-
field = fields[hash[:field]]
-
self.conditions[i][:value] = field.strongly_type(hash[:value]) if field
-
end
-
end
-
-
1
def test(properties)
-
5
fields = collection.fields.index_by &:es_code
-
5
throw :threshold, self if conditions.send(is_all_condition ? :all? : :any?) do |hash|
-
5
field = fields[hash[:field]]
-
5
if field
-
4
value = properties[hash[:field]] || field.strongly_type(value)
-
4
true if condition(hash, properties).evaluate(field, value)
-
end
-
end
-
end
-
-
1
def condition(hash, properties)
-
4
Threshold::Condition.new hash, properties
-
end
-
-
1
def self.get_thresholds_by_user(user)
-
Threshold.where(:collection_id => Collection.joins(:memberships).where("memberships.user_id = :user_id", :user_id => user.id))
-
end
-
-
1
def self.get_thresholds_with_public_collection
-
Threshold.where(:collection_id => Collection.public_collections)
-
end
-
-
1
def self.add_condition_field_kind
-
Threshold.transaction do
-
Threshold.find_each(batch_size: 100) do |threshold|
-
threshold.conditions.each do |condition|
-
begin
-
field = Field.find(condition[:field])
-
rescue ActiveRecord::RecordNotFound => e
-
field = nil
-
end
-
condition[:kind] = field.kind if field
-
end
-
threshold.save
-
end
-
end
-
end
-
-
end
-
1
module Threshold::ComparisonConcern
-
1
extend ActiveSupport::Concern
-
-
1
def eq(a, b)
-
1
a == b
-
end
-
-
# eqi - equal ignore case operator
-
1
def eqi(a, b)
-
if a.class == String and b.class == String
-
a.casecmp(b) == 0
-
elsif a.class == Fixnum and b.class == Fixnum
-
a == b
-
elsif a.class == String and b.class == Array
-
b.include? a
-
else
-
a.to_s.casecmp(b.to_s) == 0
-
end
-
end
-
-
1
def lt(a, b)
-
1
a < b
-
end
-
-
1
def lte(a, b)
-
a <= b
-
end
-
-
1
def gt(a, b)
-
2
a > b
-
end
-
-
1
def gte(a, b)
-
a >= b
-
end
-
-
1
def con(a, b)
-
not a.scan(/#{b}/i).empty?
-
end
-
-
1
def under(a, b)
-
true if b.index a
-
end
-
end
-
1
class Threshold::Condition
-
1
include Threshold::ComparisonConcern
-
-
1
attr_accessor :operator, :value
-
-
1
def initialize(hash, properties)
-
4
@operator = hash[:op]
-
4
if hash[:type] == "percentage"
-
@value = hash[:value] * (properties[hash[:compare_field]] || 0) / 100
-
else
-
4
if (hash[:value].class == FalseClass or hash[:value].class == TrueClass or hash[:value].class == Fixnum)
-
4
@value = hash[:value]
-
elsif hash[:value].class == Float
-
@value = hash[:value].to_f
-
elsif hash[:value].class == String
-
@value = hash[:value]
-
end
-
end
-
end
-
-
1
def evaluate(field, value)
-
4
if field[:kind] == "hierarchy" && value != nil && @value != nil
-
@value = field.descendants_of_in_hierarchy(@value, false)
-
end
-
4
value = value.to_s if field[:kind] == "yes_no"
-
4
return false if value.nil? || @value.nil?
-
4
send @operator, value, @value
-
end
-
end
-
1
class Alerts::Plugin < Plugin
-
-
1
collection_tab '/alerts_tab'
-
1
map_header '/alerts_map_header'
-
-
extend_model \
-
1
class: Site,
-
with: Site::TemplateConcerns
-
-
extend_model \
-
1
class: Site,
-
with: Site::AlertConcerns
-
-
1
Field::EmailField
-
field_type \
-
1
name: 'email',
-
css_class: 'lmessage',
-
small_css_class: 'smessage',
-
edit_view: 'fields/email_edit_view',
-
sample_value: 'an@email.com'
-
-
1
Field::PhoneField
-
field_type \
-
1
name: 'phone',
-
css_class: 'lphone',
-
small_css_class: 'sphone',
-
edit_view: 'fields/phone_edit_view',
-
sample_value: '85512345678'
-
-
clusterer \
-
1
map: ->(site, tmp) do
-
33
tmp[:alert_count] ||= 0
-
33
tmp[:alert_count] += (site[:alert] == 'true' ? 1 : 0)
-
33
tmp[:alert] = true if site[:alert] == 'true'
-
33
tmp[:ord] = if site[:ord] then if site[:ord].to_i < tmp[:ord].to_i then site[:ord] else tmp[:ord] end else '100' end
-
end,
-
-
reduce: ->(tmp, cluster) do
-
11
cluster[:alert_count] = tmp[:alert_count]
-
11
cluster[:color] = tmp[:alert] && tmp[:status]? Collection.find(tmp[:collection_id]).thresholds.find_by_ord(tmp[:ord]).try(:color) : ''
-
11
cluster[:alert] = tmp[:alert]
-
end
-
-
1
routes {
-
1
resources :collections do
-
1
resources :thresholds do
-
1
member do
-
1
post :set_order
-
end
-
end
-
end
-
}
-
end
-
1
class ChannelsController < ApplicationController
-
1
before_filter :authenticate_user!
-
-
1
def index
-
respond_to do |format|
-
format.html do
-
show_collection_breadcrumb
-
add_breadcrumb I18n.t('views.collections.index.properties'), collection_path(collection)
-
add_breadcrumb I18n.t('views.plugins.channels.channels'), collection_channels_path(collection)
-
end
-
format.json { render json: collection.channels.all.as_json, :root => false }
-
end
-
end
-
-
1
def new
-
-
end
-
-
end
-
1
class Channel < ActiveRecord::Base
-
1
has_many :share_channels, :dependent => :destroy
-
1
has_many :collections, :through => :share_channels
-
1
belongs_to :user
-
1
validates :name, :presence => true, :length => {:minimum => 3, :maximum => 30}, :uniqueness => {:scope => :user_id}
-
1
validates :password, :presence => true, :length => {:minimum => 4, :maximum => 6}, :if => :advanced_setup
-
1
validates :ticket_code, :presence => {:on => :create}, :if => :basic_setup
-
-
1
before_create :random_password, :unless => :national_setup
-
1
after_create :register_nuntium_channel, :unless => :national_setup
-
1
after_update :update_nuntium_channel, :unless => :national_setup
-
1
after_destroy :delete_nuntium_channel, :unless => :national_setup
-
1
attr_accessor :ticket_code
-
1
attr_accessor :phone_number
-
-
1
after_save :touch_user_lifespan
-
1
after_destroy :touch_user_lifespan
-
-
1
has_many :share_national_channels
-
1
has_many :collections, through: :share_national_channels
-
-
1
def nuntium_channel_name
-
7
national_setup ? self.name : "#{name}-#{id}"
-
end
-
-
1
def random_password
-
6
self.password = SecureRandom.base64(6) if self.password.blank?
-
end
-
-
1
def register_nuntium_channel
-
6
config = {
-
:name => self.nuntium_channel_name,
-
:kind => 'qst_server',
-
:protocol => 'sms',
-
:direction => 'bidirectional',
-
:enabled => true,
-
:restrictions => '',
-
:priority => 50,
-
:configuration => {
-
:password => self.password,
-
:friendly_name => self.name
-
}
-
}
-
-
config.merge!({
-
:ticket_code => self.ticket_code,
-
:ticket_message => "This phone will be used for updates and queries on all collections.",
-
6
}) if basic_setup
-
6
handle_nuntium_channel_response Nuntium.new_from_config.create_channel(config)
-
end
-
-
1
def handle_nuntium_channel_response(response)
-
raise get_error_from_nuntium_response(response) if not response['name'] == self.nuntium_channel_name
-
response
-
end
-
-
1
def get_error_from_nuntium_response(response)
-
return "Error processing nuntium channel" if not response['summary']
-
error = response['summary'].to_s
-
unless response['properties'].blank?
-
error << ': '
-
error << response['properties'].map do |dict|
-
dict.map{|k,v| "#{k} #{v}"}.join('; ')
-
end.join('; ')
-
end
-
error
-
end
-
-
1
def update_nuntium_channel
-
1
handle_nuntium_channel_response Nuntium.new_from_config.update_channel(
-
:name => self.nuntium_channel_name,
-
:enabled => true,
-
:restrictions => '',
-
:configuration => {
-
:friendly_name => self.name,
-
:password => self.password
-
})
-
end
-
-
1
def delete_nuntium_channel
-
Nuntium.new_from_config.delete_channel(self.nuntium_channel_name)
-
true
-
end
-
-
1
def nuntium_info
-
@nuntium_info ||= handle_nuntium_channel_response Nuntium.new_from_config.channel(self.nuntium_channel_name)
-
end
-
-
1
def self.nuntium_info_methods
-
[:client_last_activity_at, :queued_messages_count, :client_connected, :phone_number, :gateway_url]
-
end
-
-
1
def client_last_activity_at
-
nuntium_info['last_activity_at'] rescue nil
-
end
-
-
1
def queued_messages_count
-
nuntium_info['queued_ao_messages_count'] rescue nil
-
end
-
-
1
def client_connected
-
nuntium_info['connected'] rescue nil
-
end
-
-
1
def phone_number
-
nuntium_info['address'] rescue nil
-
end
-
-
1
def gateway_url
-
config = Nuntium.config
-
config['url'] + '/' + config['account'] + '/qst'
-
end
-
-
1
def self.default_nuntium_name
-
# smart or camgsm(mobitel)
-
'smart'
-
end
-
end
-
1
class ShareChannel < ActiveRecord::Base
-
1
belongs_to :channel
-
1
belongs_to :collection
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
end
-
1
class Channels::Plugin < Plugin
-
-
1
collection_tab "/channels_tab"
-
-
1
routes {
-
1
resources :collections do
-
1
resources :channels do
-
1
get :get_shared_channels, :on => :member
-
1
post :set_status, :on => :member
-
end
-
end
-
}
-
end
-
1
class FredApiController < ApplicationController
-
1
before_filter :authenticate_user!
-
1
before_filter :authenticate_collection_user!
-
1
before_filter :verify_site_belongs_to_collection!, :only => [:show_facility, :delete_facility, :update_facility]
-
1
before_filter :authenticate_site_user!, :only => [:show_facility, :delete_facility, :update_facility]
-
-
1
rescue_from Exception, :with => :default_rescue
-
1
rescue_from RuntimeError, :with => :rescue_runtime_error
-
1
rescue_from ActionController::RoutingError, :with => :rescue_record_not_found
-
1
rescue_from ActiveRecord::RecordNotFound, :with => :rescue_record_not_found
-
1
rescue_from ActiveRecord::RecordInvalid, :with => :rescue_record_invalid
-
-
1
expose(:site)
-
1
expose(:collection) { Collection.find params[:collection_id] }
-
-
1
def verify_site_belongs_to_collection!
-
if !collection.sites.include? site
-
render json: { message: "Facility #{site.id} do not belong to collection #{collection.id}"}, status: 409
-
end
-
end
-
-
1
def show_facility
-
render json: find_facility_and_apply_fred_format(site.id)
-
end
-
-
1
def delete_facility
-
site.user = current_user
-
site.destroy
-
render json: url_for_facility(site.id)
-
end
-
-
1
def update_facility
-
raw_post = request.raw_post.empty? ? "{}" : request.raw_post
-
facility_params = JSON.parse raw_post
-
-
if ["id","uuid","url","createdAt","updatedAt"].any?{|invalid_param| facility_params.include? invalid_param}
-
render json: { message: "Invalid Paramaters: The id, uuid, url, createdAt and updatedAt core properties cannot be changed by the client."}, status: 400
-
return
-
end
-
facility_params = validate_site_params(facility_params)
-
site.user = current_user
-
site.properties_will_change!
-
site.update_attributes! facility_params
-
-
render json: find_facility_and_apply_fred_format(site.id), status: :ok, :location => url_for_facility(site.id)
-
end
-
-
1
def create_facility
-
raw_post = request.raw_post.empty? ? "{}" : request.raw_post
-
facility_params = JSON.parse raw_post
-
if ["id","url","createdAt","updatedAt"].any?{|invalid_param| facility_params.include? invalid_param}
-
render json: { message: "Invalid Paramaters: The id, url, createdAt and updatedAt core properties cannot be changed by the client."}, status: 400
-
return
-
end
-
facility_params = validate_site_params(facility_params)
-
facility = collection.sites.new
-
facility.update_attributes! facility_params.merge(user: current_user)
-
facility.save!
-
render json: find_facility_and_apply_fred_format(facility.id), status: :created, :location => url_for_facility(facility.id)
-
end
-
-
1
def facilities
-
search = collection.new_search current_user_id: current_user.id
-
-
search.use_codes_instead_of_es_codes
-
-
# Sort can only be performed by a single field
-
search.sort params[:sortAsc], true if params[:sortAsc]
-
search.sort params[:sortDesc], false if params[:sortDesc]
-
-
offset = params[:offset] ? params[:offset] : 0
-
search.offset offset
-
limit = params[:limit] ? params[:limit] : 25
-
if limit == 'off'
-
search.unlimited
-
else
-
search.limit limit
-
end
-
-
#Perform queries
-
except_params = [:action, :controller, :format, :id, :collection_id, :sortAsc, :sortDesc, :offset, :limit, :fields, :name, :allProperties, :coordinates, :active, :createdAt, :updatedAt, :updatedSince, "identifiers.id", "identifiers.agency", "identifiers.context", :uuid]
-
-
# Query by Core Properties
-
search.name(params[:name]) if params[:name]
-
search.id(params[:id]) if params[:id]
-
search.uuid(params[:uuid]) if params[:uuid]
-
-
search.radius(params[:coordinates][1], params[:coordinates][0], 1) if params[:coordinates]
-
search.updated_at(params[:updatedAt]) if params[:updatedAt]
-
search.created_at(params[:createdAt]) if params[:createdAt]
-
-
# Query by updatedSince
-
search.updated_since(params[:updatedSince]) if params[:updatedSince]
-
-
# Query by Extended Properties
-
params_query = params.except(*except_params)
-
property_params = remove_prefix_form_properties_params(params_query)
-
search.where property_params
-
-
# Query by identifiers
-
if params["identifiers.context"] && params["identifiers.id"] && params["identifiers.agency"]
-
search.identifier_context_agency_and_id(params["identifiers.context"], params["identifiers.agency"], params["identifiers.id"])
-
elsif params["identifiers.agency"] && params["identifiers.id"]
-
search.identifier_agency_and_id(params["identifiers.agency"], params["identifiers.id"])
-
elsif params["identifiers.context"] && params["identifiers.id"]
-
search.identifier_context_and_id(params["identifiers.context"], params["identifiers.id"])
-
elsif params["identifiers.id"]
-
search.identifier_id(params["identifiers.id"])
-
end
-
-
#Format result
-
facilities = search.fred_api_results
-
#Hack: All facilities are active. If param[:active]=false then no results should be returned
-
facilities = [] if params[:active].to_s == false.to_s
-
-
fred_json_facilities = facilities.map {|facility| fred_facility_format_from_ES facility}
-
-
# Selection is made in memory for simplicity
-
# In the future we could use ES method fields, but the response has different structure.
-
fred_json_facilities = select_properties(fred_json_facilities, parse_fields(params[:fields])) if params[:fields]
-
-
respond_to do |format|
-
format.json { render json: {facilities: fred_json_facilities} }
-
end
-
-
end
-
-
1
private
-
-
# Remove 'properties.' prefix form params
-
1
def remove_prefix_form_properties_params(params_query)
-
res = {}
-
params_query.each_pair do |key, val|
-
res[key.gsub(/properties./, "")] = val
-
end
-
res
-
end
-
-
1
def find_facility_and_apply_fred_format(id)
-
search = collection.new_search current_user_id: current_user.id
-
search.id(id)
-
results = search.fred_api_results
-
-
# ID is unique. We should only get one result here.
-
facility = results[0]
-
-
fred_facility_format_from_ES(facility)
-
end
-
-
1
def validate_site_params(facility_param)
-
-
if facility_param.include? "active"
-
facility_param.delete("active")
-
end
-
-
fields = collection.fields.index_by(&:code)
-
properties = facility_param["properties"] || {}
-
-
properties_with_identifiers = properties.merge(convert_to_properties(facility_param["identifiers"]))
-
-
properties_by_es_code = {}
-
properties_with_identifiers.each_pair do |code, value|
-
field = fields[code]
-
if field.nil?
-
raise "Invalid Parameters: Cannot find Field with code equal to '#{code}' in Collection's Layers."
-
end
-
properties_by_es_code["#{field.es_code}"] = field.decode_fred value
-
end
-
-
properties_with_identifiers = properties_by_es_code
-
-
lat = facility_param["coordinates"][1] if facility_param["coordinates"]
-
lng = facility_param["coordinates"][0] if facility_param["coordinates"]
-
-
facility_param.delete "coordinates"
-
facility_param.delete "identifiers"
-
-
validated_site = facility_param
-
validated_site["properties"] = properties_with_identifiers
-
validated_site["lat"] = lat
-
validated_site["lng"] = lng
-
-
validated_site
-
end
-
-
1
def convert_to_properties(params_idetifiers)
-
identifiers = params_idetifiers || []
-
as_properties = {}
-
identifiers_fields = collection.fields.find_all{|f| f.identifier?}
-
identifiers.each do |identifier|
-
field = identifiers_fields.find{|f| f.context == identifier["context"] && f.agency == identifier["agency"] }
-
raise "Invalid Parameters: Cannot find Identifier Field with context equal to '#{identifier["context"]}' and agency equal to '#{identifier["agency"]}' in Collection's Layers." if field.nil?
-
as_properties["#{field.code}"] = identifier["id"]
-
end
-
as_properties
-
end
-
-
1
def select_properties(facilities, fields_list)
-
filtered_facilities = []
-
facilities.each do |facility|
-
filtered_facility = facility.select{|key,value| fields_list[:default].include?(key.to_s) }
-
properties = facility[:properties].select{|key,value| fields_list[:custom].include?(key) }
-
filtered_facility[:properties] = properties if properties.length > 0
-
-
filtered_facilities << filtered_facility
-
end
-
filtered_facilities
-
end
-
-
# field_list_string has format fields=name,id,properties:numBeds
-
1
def parse_fields(field_list_string)
-
# #=> ["name,id", ",properties:", "numBeds"]
-
field_list_match = field_list_string.partition(/,properties:/)
-
{ default: field_list_match[0].split(',') , custom: field_list_match[2].split(',')}
-
end
-
-
1
def url_for_facility(id)
-
url_for(:controller => 'fred_api', :action => 'show_facility',:format => :json, :id => id)
-
end
-
-
1
def fred_facility_format_from_ES(result)
-
source = result['_source']
-
-
obj = {}
-
obj[:name] = source['name']
-
obj[:uuid] = source['uuid']
-
-
obj[:createdAt] = format_time_to_iso_string(source['created_at'])
-
obj[:updatedAt] = format_time_to_iso_string(source['updated_at'])
-
if source['location']
-
obj[:coordinates] = [source['location']['lon'], source['location']['lat']]
-
end
-
-
# ResourceMap does not implement logical deletion yet. Thus all facilities are active.
-
obj[:active] = true
-
-
obj[:href] = url_for_facility(source['id'])
-
-
obj[:identifiers] = source['identifiers']
-
-
obj[:properties] = source['properties']
-
-
obj
-
end
-
-
1
def format_time_to_iso_string(es_format_date_sting)
-
date = Site.parse_time(es_format_date_sting).utc
-
date.iso8601
-
end
-
-
1
def rescue_record_invalid(ex)
-
if ex.record.errors[:uuid].include?("has already been taken")
-
render json: {code: "409 Conflict", message: "Duplicated facility: UUID has already been taken in this collection."}, :status => 409, :layout => false
-
else
-
render json: {code: "400 Record Invalid", message: "#{ex.message}"}, :status => 400, :layout => false
-
end
-
end
-
-
1
def rescue_runtime_error(ex)
-
render json: {code: "400 Record Invalid", message: "#{ex.message}"}, :status => 400, :layout => false
-
end
-
-
1
def default_rescue(ex)
-
puts ex.message
-
render json: {code: "500 Internal Server Error", message: "#{ex.message}"}, status: 500, :layout => false
-
end
-
-
1
def rescue_record_not_found(ex)
-
render json: { code: "404 Not Found", message: "Resource not found" }, :status => 404, :layout => false
-
end
-
end
-
1
module Field::FredApiConcern
-
1
extend ActiveSupport::Concern
-
-
1
def identifier?
-
kind == 'identifier'
-
end
-
-
1
def context
-
config['context'] rescue nil
-
end
-
-
1
def agency
-
config['agency'] rescue nil
-
end
-
-
1
def fred_api_value(value)
-
if date?
-
# Values are stored in ISO 8601 format.
-
value
-
else
-
api_value(value)
-
end
-
end
-
end
-
1
class Field::IdentifierField < Field
-
1
IdentifierKinds = ['Normal', 'Luhn']
-
-
1
def value_type_description
-
"identifier values"
-
end
-
-
1
def value_hint
-
format_implementation.value_hint
-
end
-
-
1
def valid_value?(*args)
-
format_implementation.valid_value?(*args)
-
end
-
-
1
def decode(*args)
-
format_implementation.decode(*args)
-
end
-
-
1
def default_value_for_create(collection)
-
format_implementation.default_value_for_create(collection)
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
format_implementation.error_description_for_invalid_values(exception)
-
end
-
-
1
def format_implementation
-
"Field::IdentifierField::#{config['format'] || 'Normal'}".constantize.new(self)
-
end
-
end
-
-
1
class Field::IdentifierField::FormatImplementation
-
1
def initialize(field)
-
@field = field
-
end
-
-
1
def valid_value?(value, site)
-
true
-
end
-
-
1
def decode(value)
-
value
-
end
-
-
1
def default_value_for_create(collection)
-
nil
-
end
-
-
1
def value_hint
-
nil
-
end
-
-
1
def error_description_for_invalid_values(exception)
-
"are not valid for the type identifier"
-
end
-
end
-
-
1
class Field::IdentifierField::Normal < Field::IdentifierField::FormatImplementation
-
end
-
-
1
class Field::IdentifierField::Luhn < Field::IdentifierField::FormatImplementation
-
1
def error_description_for_invalid_values(exception)
-
"are not valid for the type luhn identifier: #{exception}"
-
end
-
-
1
def value_hint
-
"Luhn identifiers must be in this format: nnnnnn-n (where 'n' is a number), must be unique and pass the luhn check."
-
end
-
-
1
def decode(value)
-
value
-
end
-
-
1
def valid_value?(value, site)
-
-
unless value =~ /(\d\d\d\d\d\d)\-(\d)/
-
raise "the value must be in this format: nnnnnn-n (where 'n' is a number)"
-
end
-
-
verifier = compute_luhn_verifier($1)
-
if verifier != $2.to_i
-
raise "the value failed the luhn check"
-
end
-
-
field_es_code = "properties.#{@field.es_code}"
-
search = @field.collection.new_search
-
search.select_fields [field_es_code]
-
search.eq @field, value
-
results = search.results
-
if results.length == 1
-
if site && results.results.any? { |r| r["_id"].to_s == site.id.to_s }
-
return value
-
end
-
raise "the value already exists in the collection"
-
end
-
-
true
-
end
-
-
1
def compute_luhn_verifier(str)
-
n = str.length - 1
-
even = false
-
sum = 0
-
while n >= 0
-
digit = str[n].to_i
-
-
if even
-
if digit < 5
-
sum += digit
-
else
-
sum += 1 + (digit - 5) * 2
-
end
-
else
-
sum += digit
-
end
-
-
even = !even
-
-
n -= 1
-
end
-
-
(10 - sum) % 10
-
end
-
-
1
def default_value_for_create(collection)
-
field_es_code = "properties.#{@field.es_code}"
-
search = collection.new_search
-
search.select_fields [field_es_code]
-
search.sort field_es_code, true
-
results = search.results
-
-
return "100000-9" if results.empty?
-
-
last = nil
-
-
results.results.each do |result|
-
result = result["fields"]
-
next unless result
-
value = result[field_es_code]
-
next unless value
-
-
value = value[0 ... 6].to_i
-
if last && value - last > 1
-
break
-
end
-
last = value
-
end
-
-
next_luhn(last)
-
end
-
-
1
def next_luhn(max)
-
"#{max + 1}-#{compute_luhn_verifier((max + 1).to_s)}"
-
end
-
end
-
1
module Search::FredApiConcern
-
# Returns the results from ElasticSearch but with codes as keys and codes as
-
# values (when applicable).
-
1
def fred_api_results
-
visible_fields = @collection.visible_fields_for(@current_user, snapshot_id: @snapshot_id)
-
-
fields_by_es_code = visible_fields.index_by &:es_code
-
-
items = results()
-
-
items.each do |item|
-
properties = item['_source']['properties']
-
item['_source']['identifiers'] = []
-
item['_source']['properties'] = {}
-
-
properties.each_pair do |es_code, value|
-
field = fields_by_es_code[es_code]
-
if field
-
if field.identifier?
-
item['_source']['identifiers'] << {:agency => field.agency, :context => field.context , :id => value}
-
end
-
item['_source']['properties'][field.code] = field.fred_api_value(value)
-
end
-
end
-
end
-
-
items
-
end
-
-
1
def identifier_id(identifier_value)
-
identifiers_proc = Proc.new {@collection.fields.find_all{|f|f.identifier?}.map{|i| i.es_code }}
-
query_identifier(identifiers_proc, identifier_value)
-
end
-
-
1
def identifier_context_and_id(context_value, identifier_value)
-
identifiers_proc = Proc.new { @collection.fields.find_all{|f|f.identifier? && f.context == context_value}.map{|i| i.es_code }}
-
query_identifier(identifiers_proc, identifier_value)
-
end
-
-
1
def identifier_context_agency_and_id(context_value, agency_value, identifier_value)
-
identifiers_proc = Proc.new { @collection.fields.find_all{|f|f.identifier? && f.agency == agency_value && f.context == context_value}.map{|i| i.es_code }}
-
query_identifier(identifiers_proc, identifier_value)
-
end
-
-
1
def identifier_agency_and_id(agency_value, identifier_value)
-
identifiers_proc = Proc.new { @collection.fields.find_all{|f|f.identifier? && f.agency == agency_value}.map{|i| i.es_code }}
-
query_identifier(identifiers_proc, identifier_value)
-
end
-
-
1
def query_identifier(identifiers_proc, identifier_value)
-
identifiers = identifiers_proc.call()
-
if identifiers.empty?
-
# there is no identifiers that satisfy the condition => the result should be an empty list
-
add_filter limit: {value: 0}
-
else
-
terms = identifiers.map{ |id_es_code| {:terms => { id_es_code => [identifier_value] }} }
-
add_filter or: terms
-
end
-
self
-
end
-
end
-
1
module Site::UuidConcern
-
1
extend ActiveSupport::Concern
-
-
1
included do
-
1
validates :uuid, :presence => true, :unchangeable => true
-
1
validate :validate_uuid_format
-
1
validates :uuid, :uniqueness => { :scope => :collection_id }
-
-
1
before_validation :set_uuid, :on => :create
-
end
-
-
1
def validate_uuid_format
-
760
begin
-
760
uuid = UUIDTools::UUID.parse self.uuid
-
rescue
-
errors.add(:uuid, "is not valid")
-
end
-
760
errors.add(:uuid, "is not valid") if uuid && !uuid.valid?
-
end
-
-
1
def set_uuid
-
672
if !self.uuid
-
637
self.uuid = UUIDTools::UUID.random_create.to_s
-
end
-
end
-
end
-
-
1
class UnchangeableValidator < ActiveModel::EachValidator
-
1
def validate_each(object, attribute, value)
-
760
if !object.new_record? && value.present?
-
88
original = object.class.send(:where, "id = #{object.id}").select("id, #{attribute.to_s}").first
-
88
if original.send(attribute) != value
-
object.errors[attribute] << (options[:message] || "cannot be changed once assigned")
-
end
-
end
-
end
-
end
-
1
class FredApi::Plugin < Plugin
-
1
Field::IdentifierField
-
field_type \
-
1
name: 'identifier',
-
css_class: 'lgovernment',
-
small_css_class: 'sgovernment',
-
edit_view: 'fields/identifier_edit_view',
-
property_editor: 'fields/identifier_editor',
-
sample_value: 'XYZ123'
-
-
extend_model \
-
1
class: Field,
-
with: Field::FredApiConcern
-
-
extend_model \
-
1
class: Search,
-
with: Search::FredApiConcern
-
-
extend_model \
-
1
class: Site,
-
with: Site::UuidConcern
-
-
-
1
routes {
-
1
match 'collections/:collection_id/fred_api/v1/facilities/:id' => 'fred_api#show_facility', :via => :get, as: :show_facility
-
1
match 'collections/:collection_id/fred_api/v1/facilities' => 'fred_api#facilities', :via => :get, as: :facilities
-
1
match 'collections/:collection_id/fred_api/v1/facilities/:id' => 'fred_api#delete_facility', :via => :delete, as: :delete_facility
-
1
match 'collections/:collection_id/fred_api/v1/facilities' => 'fred_api#create_facility', :via => :post, as: :create_facility
-
1
match 'collections/:collection_id/fred_api/v1/facilities/:id' => 'fred_api#update_facility', :via => :put, as: :update_facility
-
}
-
end
-
1
class RemindersController < ApplicationController
-
1
before_filter :authenticate_user!
-
-
1
def index
-
respond_to do |format| format.html do
-
show_collection_breadcrumb
-
add_breadcrumb I18n.t('views.collections.index.properties'), collection_path(collection)
-
add_breadcrumb I18n.t('views.collections.tab.reminders'), collection_reminders_path(collection)
-
end
-
all_reminders = reminders.all.as_json(include: [:repeat], methods: [:reminder_date], except: [:schedule])
-
format.json { render json: apply_time_zone(all_reminders), :root => false}
-
end
-
end
-
-
1
def create
-
if params[:reminder]["time_zone"]
-
date_and_time = '%m-%d-%YT%H:%M:%S %Z'
-
params[:reminder]["reminder_date"] = ActiveSupport::TimeZone[params[:reminder]["time_zone"]].parse(params[:reminder]["reminder_date"]).to_s
-
end
-
reminder = reminders.new reminder_params
-
reminder.sites = Site.select("id, collection_id, name, properties").find params[:reminder][:sites] if params[:reminder][:sites]
-
reminder.save!
-
render json: reminder
-
end
-
-
1
def update
-
reminder = reminders.find params[:id]
-
if params[:reminder]["time_zone"]
-
date_and_time = '%m-%d-%YT%H:%M:%S %Z'
-
params[:reminder]["reminder_date"] = ActiveSupport::TimeZone[params[:reminder]["time_zone"]].parse(params[:reminder]["reminder_date"]).to_s
-
end
-
reminder.update_attributes! reminder_params
-
reminder.sites = Site.select("id, collection_id, name, properties").find params[:reminder][:sites] if params[:reminder][:sites]
-
-
reminder.save!
-
render json: reminder
-
end
-
-
1
def destroy
-
reminder.destroy
-
render json: reminder
-
end
-
-
1
def set_status
-
reminder.update_attribute :status, params[:status]
-
render json: reminder
-
end
-
-
1
def get_time_zone
-
time_zones = []
-
ActiveSupport::TimeZone.all.inject([]) do |result, tz|
-
utc_offset = tz.utc_offset / 3600
-
time_zones << {:identifier => "#{tz.name}", :text => "(GMT #{'%.2f' % utc_offset}): #{tz.name}"}
-
end
-
render :json => {:list_time_zone => time_zones, :user_time_zone => current_user.time_zone}, :root => false
-
end
-
-
1
def apply_time_zone reminders
-
arr = []
-
reminders.each do |r|
-
r["next_run"] = r["next_run"].in_time_zone(r["time_zone"]) if r["time_zone"]
-
r["reminder_date"] = r["reminder_date"].in_time_zone(r["time_zone"]) if r["time_zone"]
-
arr.push r
-
end
-
arr
-
end
-
-
1
def reminder_params
-
params.require(:reminder).permit(:name, :reminder_message, :reminder_date, :repeat_id, :collection_id, :time_zone, :is_all_site)
-
end
-
end
-
1
class Reminder < ActiveRecord::Base
-
1
belongs_to :collection
-
1
belongs_to :repeat
-
1
serialize :schedule, IceCube::Schedule
-
1
serialize :sites, Array
-
1
before_save :set_schedule_rule
-
1
before_save :set_next_run
-
-
1
after_save :touch_collection_lifespan
-
1
after_destroy :touch_collection_lifespan
-
-
1
def reminder_date
-
schedule.try(:start_time)
-
end
-
-
1
def reminder_date=(date)
-
self.schedule ||= IceCube::Schedule.new
-
date = case date
-
when String then Time.parse(date)
-
when Time then date
-
else raise "Invalid date time. Should be Time or String"
-
end
-
schedule.start_time = date
-
end
-
-
1
def set_schedule_rule
-
self.schedule = IceCube::Schedule.new(reminder_date)
-
self.schedule.add_recurrence_rule(repeat.rule)
-
end
-
-
1
def set_next_run
-
self.next_run = schedule.next_occurrence
-
end
-
-
1
def target_sites
-
if is_all_site
-
collection.sites
-
else
-
sites
-
end
-
end
-
-
1
def self.reset_reminders_recurrence_rule
-
all.each { |reminder| reminder.update_attributes reminder_date: reminder.reminder_date }
-
end
-
end
-
1
class Repeat < ActiveRecord::Base
-
1
serialize :rule, IceCube::Rule
-
end
-
1
class Reminders::Plugin < Plugin
-
-
1
collection_tab '/reminder_tab'
-
-
schedule \
-
1
every: "1m",
-
class: "ReminderTask",
-
queue: 'reminder_queue'
-
-
1
routes {
-
1
resources :collections do
-
1
resources :reminders do
-
1
post :set_status, :on => :member
-
end
-
end
-
-
1
match 'get_time_zone' => "reminders#get_time_zone", :via => :get
-
}
-
end
-
1
require 'machinist/active_record'
-
1
require 'sham'
-
1
require 'faker'
-
-
1
def rand_in_range(from, to)
-
12
rand * (to - from) + from
-
end
-
-
1
def rand_time(from, to)
-
12
Time.at(rand_in_range(from.to_f, to.to_f))
-
end
-
-
1
Sham.define do
-
12267
name { Faker::Name.name }
-
6133
email { Faker::Internet.email }
-
6131
phone_number { rand(1111111..9999999) }
-
6133
password { Faker::Internet.password(15, 15, true, false) }
-
13
username { Faker::Internet.user_name }
-
37
color { "##{rand(255**3).to_s(16)}" }
-
13
icon { Faker::Name.name }
-
37
sn { |i| i }
-
end
-
-
1
User.blueprint do
-
1676
email
-
1676
password
-
1676
phone_number
-
3351
confirmed_at { Time.now }
-
end
-
-
1
Collection.blueprint do
-
687
name
-
1374
icon {'default'}
-
end
-
-
1
Site.blueprint do
-
583
collection
-
583
name
-
1112
lat { rand(179) - 89 }
-
1112
lng { rand(359) - 179 }
-
1166
user { User.make }
-
end
-
-
1
Layer.blueprint do
-
467
collection
-
467
name
-
931
ord { collection.next_layer_ord }
-
876
user { User.make }
-
end
-
-
1
Field.subclasses.each do |field_kind|
-
14
field_kind.name.constantize.blueprint do
-
1852
layer
-
3674
collection { layer.collection }
-
1852
name
-
1938
code { Sham.name }
-
3605
ord { layer.next_field_ord }
-
end
-
end
-
-
1
Activity.blueprint do
-
end
-
-
1
SiteHistory.blueprint do
-
1
collection
-
1
name
-
2
lat { rand(180) - 90 }
-
2
lng { rand(360) - 180 }
-
2
valid_since {rand_time(2.days.ago, Time.now)}
-
1
valid_to nil
-
end
-
-
1
Threshold.blueprint do
-
16
collection
-
32
ord { Sham.sn }
-
32
color { Sham.color }
-
end
-
-
1
Snapshot.blueprint do
-
11
collection
-
22
date {rand_time(2.days.ago, Time.now)}
-
22
name { Sham.username }
-
end
-
-
1
UserSnapshot.blueprint do
-
6
snapshot
-
6
user
-
end
-
-
1
Repeat.blueprint do
-
rule { IceCube::Rule.weekly }
-
end
-
-
1
Reminder.blueprint do
-
repeat
-
end
-
-
1
Channel.blueprint do
-
5
user
-
end
-
-
1
Membership.blueprint do
-
33
user
-
33
collection
-
66
admin { false }
-
end
-
-
1
ImportJob.blueprint do
-
user
-
collection
-
status
-
end
-
-
1
LayerMembership.blueprint do
-
6
collection
-
12
read { false }
-
12
write { false }
-
6
user
-
end
-
-
1
SiteReminder.blueprint do
-
end
-
-
1
SitesPermission.blueprint do
-
end
-
1
require 'spec_helper'
-
-
1
describe AndroidController do
-
1
include Devise::TestHelpers
-
10
let!(:user) { User.make }
-
10
let!(:collection1) { user.create_collection(Collection.make_unsaved) }
-
10
let!(:collection2) { user.collections.make }
-
10
let!(:layer) { collection1.layers.make }
-
-
10
let!(:text) { layer.text_fields.make :code => 'text' }
-
10
let!(:numeric) { layer.numeric_fields.make :code => 'numeric'}
-
-
10
before(:each) {sign_in user}
-
-
1
describe "Get JSON collections" do
-
1
before(:each) do
-
2
get :collections_json
-
end
-
-
2
it { expect(response).to be_success }
-
1
it "should response in JSON format" do
-
1
expect(response.content_type).to eq 'application/json'
-
end
-
end
-
-
1
describe "submission" do
-
1
before(:each) do
-
2
@xml = "<?xml version='1.0' ?>
-
<site>
-
<collection-id type='integer'>%(:collection_id)<\/collection-id>
-
<name>Cambodiana<\/name>
-
<lat type='float'>11.53<\/lat>
-
<lng type='float'>104.93<\/lng>
-
<existing-fields>
-
<field-#{text.id}>
-
<field-id>#{text.id}<\/field-id>
-
<value>Who know?<\/value>
-
<\/field-#{text.id}>
-
<field-#{numeric.id}>
-
<field-id>#{numeric.id}<\/field-id>
-
<value>10<\/value>
-
<\/field-#{numeric.id}>
-
<\/existing-fields>
-
<\/site>"
-
-
end
-
-
1
it "should post submission" do
-
1
@xml = @xml.gsub("%(:collection_id)",collection1.id.to_s)
-
2
File.open("spec/fixtures/instant_file.xml","w") { |f| f.puts @xml }
-
1
xml_file = fixture_file_upload('/instant_file.xml', 'text/xml')
-
-
1
post :submission, :xml_submission_file => xml_file
-
1
expect(response).to be_success
-
end
-
-
1
it "should response Unauthorized if user is not an admin" do
-
1
@xml = @xml.gsub("%(:collection_id)",collection2.id.to_s)
-
2
File.open("spec/fixtures/instant_file.xml","w") { |f| f.puts @xml }
-
1
xml_file = fixture_file_upload('/instant_file.xml', 'text/xml')
-
-
1
post :submission, :xml_submission_file => xml_file
-
1
expect(response.response_code).to eq(401)
-
1
expect(response).not_to be_success
-
-
end
-
end
-
-
1
describe "helper methods" do
-
1
context "Render Xform" do
-
1
before(:each) do
-
5
@result = controller.render_xform(collection1)
-
-
end
-
1
it "should render Xform's title with collection's name" do
-
1
expect(@result).to match(/<h:title>#{collection1.name}<\/h:title>/)
-
end
-
1
it "should render collection id in the xform's model" do
-
1
expect(@result).to match(/<collection-id type=\"integer\">#{collection1.id}<\/collection-id>/)
-
end
-
1
it "should render the model elements for existing fields in the xform's model" do
-
1
text_field = /<field-#{text.id}><field-id>#{text.id}<\/field-id><value \/><\/field-#{text.id}>/
-
1
numeric_field = /<field-#{numeric.id}><field-id>#{numeric.id}<\/field-id><value \/><\/field-#{numeric.id}>/
-
1
fields = /#{text_field}#{numeric_field}/
-
1
expect(@result).to match(fields)
-
end
-
1
it "should render the binding elements for existing fields in the xform's model" do
-
1
text_field = /<bind nodeset=\"\/site\/existing-fields\/field-#{text.id}\/value\" \/>/
-
1
numeric_field = /<bind nodeset=\"\/site\/existing-fields\/field-#{numeric.id}\/value\" \/>/
-
1
fields = /#{text_field}#{numeric_field}/
-
1
expect(@result).to match(fields)
-
end
-
1
it "should render the ui elements for existing fields in the xform's body" do
-
1
text_field = /<input ref=\"\/site\/existing-fields\/field-#{text.id}\/value\"><label>#{text.name}<\/label><\/input>/
-
1
numeric_field = /<input ref=\"\/site\/existing-fields\/field-#{numeric.id}\/value\"><label>#{numeric.name}<\/label><\/input>/
-
1
fields = /#{text_field}#{numeric_field}/
-
1
expect(@result).to match(fields)
-
end
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Api::CollectionsController, type: :controller do
-
1
include Devise::TestHelpers
-
1
render_views
-
-
18
let!(:user) { User.make time_zone: 'UTC' }
-
18
let!(:collection) { user.create_collection(Collection.make) }
-
18
let!(:layer) { collection.layers.make }
-
-
18
let!(:text) { layer.text_fields.make :code => 'text'}
-
18
let!(:numeric) { layer.numeric_fields.make :code => 'numeric' }
-
18
let!(:yes_no) { layer.yes_no_fields.make :code => 'yes_no'}
-
18
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
18
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
1
config_hierarchy = [{ id: 'dad', name: 'Dad', sub: [{id: 'son', name: 'Son'}, {id: 'bro', name: 'Bro'}]}]
-
18
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
18
let!(:site_ref) { layer.site_fields.make :code => 'site' }
-
18
let!(:date) { layer.date_fields.make :code => 'date' }
-
18
let!(:director) { layer.user_fields.make :code => 'user'}
-
-
1
let!(:site2) {
-
17
collection.sites.make :name => "Site A", properties: { hierarchy.es_code => 'bro' }
-
}
-
-
18
let!(:site) { collection.sites.make :name => "Site B", :properties => {
-
text.es_code => 'foo',
-
numeric.es_code => 1,
-
yes_no.es_code => true,
-
select_one.es_code => 1,
-
select_many.es_code => [1, 2],
-
hierarchy.es_code => 'dad',
-
site_ref.es_code => site2.id,
-
date.es_code => "2012-10-24T00:00:00Z",
-
director.es_code => user.email }
-
}
-
-
18
before(:each) { sign_in user }
-
-
1
describe "GET collection" do
-
1
before(:each) do
-
1
get :show, id: collection.id, format: 'json'
-
end
-
-
1
it 'should assign time_zone from login user' do
-
1
expect(controller.collection.time_zone).to eq user.time_zone
-
end
-
end
-
-
1
describe "GET JSON collection" do
-
1
before(:each) do
-
2
get :show, id: collection.id, format: 'json'
-
end
-
-
2
it { expect(response).to be_success }
-
-
1
it "should return JSON" do
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq(collection.name)
-
3
json['sites'].sort_by! { |site| site["name"] }
-
1
expect(json["sites"].length).to eq(2)
-
-
1
expect(json["sites"][0]["id"]).to eq(site2.id)
-
1
expect(json["sites"][0]["name"]).to eq(site2.name)
-
1
expect(json["sites"][0]["lat"]).to eq(site2.lat)
-
1
expect(json["sites"][0]["long"]).to eq(site2.lng)
-
-
1
expect(json["sites"][0]["properties"].length).to eq(1)
-
-
1
expect(json["sites"][0]["properties"][hierarchy.code]).to eq("Bro")
-
-
1
expect(json["sites"][1]["id"]).to eq(site.id)
-
1
expect(json["sites"][1]["name"]).to eq(site.name)
-
1
expect(json["sites"][1]["lat"]).to eq(site.lat)
-
1
expect(json["sites"][1]["long"]).to eq(site.lng)
-
-
1
expect(json["sites"][1]["properties"].length).to eq(9)
-
-
1
expect(json["sites"][1]["properties"][text.code]).to eq(site.properties[text.es_code])
-
1
expect(json["sites"][1]["properties"][yes_no.code]).to be_truthy
-
1
expect(json["sites"][1]["properties"][numeric.code]).to eq(site.properties[numeric.es_code])
-
1
expect(json["sites"][1]["properties"][select_one.code]).to eq('one')
-
1
expect(json["sites"][1]["properties"][select_many.code]).to eq(['one', 'two'])
-
1
expect(json["sites"][1]["properties"][hierarchy.code]).to eq("Dad")
-
1
expect(json["sites"][1]["properties"][site_ref.code]).to eq(site2.id)
-
1
expect(json["sites"][1]["properties"][date.code]).to eq('10/24/2012')
-
1
expect(json["sites"][1]["properties"][director.code]).to eq(user.email)
-
-
end
-
end
-
-
1
describe "GET JSON collection with query fieldeters" do
-
-
1
it "should retrieve sites under certain item in a hierarchy field" do
-
1
get :show, id: collection.id, format: 'json', hierarchy.code => { under: 'Dad' }
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["sites"].length).to eq(2)
-
expect(json["sites"][0]["id"]).to eq(site2.id)
-
expect(json["sites"][1]["id"]).to eq(site.id)
-
end
-
end
-
-
1
describe "GET RSS collection" do
-
1
before(:each) do
-
2
get :show, id: collection.id, format: 'rss'
-
end
-
-
2
it { expect(response).to be_success }
-
-
1
it "should return RSS" do
-
1
rss = Hash.from_xml response.body
-
-
1
expect(rss["rss"]["channel"]["title"]).to eq(collection.name)
-
3
rss["rss"]["channel"]["item"].sort_by! { |item| item["name"] }
-
-
1
expect(rss["rss"]["channel"]["item"][0]["title"]).to eq(site2.name)
-
1
expect(rss["rss"]["channel"]["item"][0]["lat"]).to eq(site2.lat.to_s)
-
1
expect(rss["rss"]["channel"]["item"][0]["long"]).to eq(site2.lng.to_s)
-
1
expect(rss["rss"]["channel"]["item"][0]["guid"]).to eq(api_site_url site2, format: 'rss')
-
-
#TODO: This is returning "properties"=>"\n "
-
1
expect(rss["rss"]["channel"]["item"][0]["properties"].length).to eq(1)
-
-
1
expect(rss["rss"]["channel"]["item"][0]["properties"][hierarchy.code]).to eq('Bro')
-
-
1
expect(rss["rss"]["channel"]["item"][1]["title"]).to eq(site.name)
-
1
expect(rss["rss"]["channel"]["item"][1]["lat"]).to eq(site.lat.to_s)
-
1
expect(rss["rss"]["channel"]["item"][1]["long"]).to eq(site.lng.to_s)
-
1
expect(rss["rss"]["channel"]["item"][1]["guid"]).to eq(api_site_url site, format: 'rss')
-
-
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"].length).to eq(9)
-
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][text.code]).to eq(site.properties[text.es_code])
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][numeric.code]).to eq(site.properties[numeric.es_code].to_s)
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][yes_no.code]).to eq('true')
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][select_one.code]).to eq('one')
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][select_many.code].length).to eq(1)
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][select_many.code]['option'].length).to eq(2)
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][select_many.code]['option'][0]['code']).to eq('one')
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][select_many.code]['option'][1]['code']).to eq('two')
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][hierarchy.code]).to eq('Dad')
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][site_ref.code]).to eq(site2.id.to_s)
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][date.code]).to eq('10/24/2012')
-
1
expect(rss["rss"]["channel"]["item"][1]["properties"][director.code]).to eq(user.email)
-
-
-
end
-
-
end
-
-
1
describe "GET CSV collection" do
-
1
before(:each) do
-
2
get :show, id: collection.id, format: 'csv'
-
end
-
-
2
it { expect(response).to be_success }
-
-
1
it "should return CSV" do
-
1
csv = CSV.parse response.body
-
1
site2_updated_at = site2.updated_at.to_datetime.rfc822
-
1
site1_updated_at = site.updated_at.to_datetime.rfc822
-
1
expect(csv.length).to eq(3)
-
1
expect(csv[0]).to eq(['resmap-id', 'name', 'lat', 'long', text.code, numeric.code, yes_no.code, select_one.code, 'select_many', 'hierarchy', site_ref.code, date.code, director.code, 'last updated'])
-
1
expect(csv.include?([site2.id.to_s, site2.name, site2.lat.to_s, site2.lng.to_s, "", "", "no", "", "", "Bro", "", "", "", site2_updated_at])).to eq(true)
-
1
expect(csv.include?([site.id.to_s, site.name, site.lat.to_s, site.lng.to_s, site.properties[text.es_code], site.properties[numeric.es_code].to_s, "yes", "one", "one, two", "Dad", site2.id.to_s, "10/24/2012", user.email, site1_updated_at])).to eq(true)
-
end
-
end
-
-
1
describe "GET SHP collection" do
-
1
before(:each) do
-
1
get :show, id: collection.id, format: 'shp'
-
end
-
-
2
it { expect(response).to be_success }
-
end
-
-
1
describe "GET some sites from collection" do
-
1
before(:each) do
-
1
get :show, id: collection.id, format: 'shp'
-
end
-
-
1
it "should return some sites based on provided ids params" do
-
1
get :get_some_sites ,sites: [site.id, site2.id].join(","), format: 'json', id: collection.id
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json.length).to eq(2)
-
end
-
end
-
-
1
describe "validate query fields" do
-
-
1
it "should validate numeric fields in equal queries" do
-
1
get :show, id: collection.id, format: 'csv', numeric.code => "<=invalid"
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid numeric value in field numeric")
-
1
get :show, id: collection.id, format: 'csv', numeric.code => "2"
-
1
expect(response.response_code).to be(200)
-
end
-
-
1
it "should validate numeric fields in other operations" do
-
1
get :show, id: collection.id, format: 'csv', numeric.code => "<=invalid"
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid numeric value in field numeric")
-
1
get :show, id: collection.id, format: 'csv', numeric.code => "<=2"
-
1
expect(response.response_code).to be(200)
-
end
-
-
1
it "should validate date fields format" do
-
1
get :show, id: collection.id, format: 'csv', date.code => "invalid1234"
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid date value in field date")
-
end
-
-
1
it "should validate date fields format values" do
-
1
get :show, id: collection.id, format: 'csv', date.code => "32/4,invalid"
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid date value in field date")
-
1
get :show, id: collection.id, format: 'csv', date.code => "12/25/2012,12/31/2012"
-
1
expect(response.response_code).to be(200)
-
end
-
-
1
it "should validate hierarchy existing option" do
-
1
get :show, id: collection.id, format: 'csv', hierarchy.code => ["invalid"]
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid hierarchy option in field hierarchy")
-
1
get :show, id: collection.id, format: 'csv', hierarchy.code => ["Dad"]
-
1
expect(response.response_code).to be(200)
-
end
-
-
1
it "should validate select_one existing option" do
-
1
get :show, id: collection.id, format: 'csv', select_one.code => "invalid"
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid option in field select_one")
-
1
get :show, id: collection.id, format: 'csv', select_one.code => "one"
-
1
expect(response.response_code).to be(200)
-
end
-
-
1
it "should validate select_many existing option" do
-
1
get :show, id: collection.id, format: 'csv', select_many.code => "invalid"
-
1
expect(response.response_code).to be(400)
-
1
expect(response.body).to include("Invalid option in field select_many")
-
1
get :show, id: collection.id, format: 'csv', select_many.code => "one"
-
1
expect(response.response_code).to be(200)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Api::SitesController, type: :controller do
-
1
include Devise::TestHelpers
-
-
9
let!(:user) { User.make }
-
9
let!(:collection) { user.create_collection(Collection.make_unsaved) }
-
9
let!(:collection2) { user.create_collection(Collection.make_unsaved) }
-
-
9
let!(:layer) { collection.layers.make }
-
-
9
let!(:text) { layer.text_fields.make :code => 'text'}
-
9
let!(:numeric) { layer.numeric_fields.make :code => 'numeric' }
-
9
let!(:yes_no) { layer.yes_no_fields.make :code => 'yes_no'}
-
9
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
9
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
1
config_hierarchy = [{ id: 'dad', name: 'Dad', sub: [{id: 'son', name: 'Son'}, {id: 'bro', name: 'Bro'}]}]
-
9
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
9
let!(:site_ref) { layer.site_fields.make :code => 'site' }
-
9
let!(:date) { layer.date_fields.make :code => 'date' }
-
9
let!(:director) { layer.user_fields.make :code => 'user'}
-
-
9
let!(:site) { collection.sites.make }
-
9
let!(:site1) { collection.sites.make }
-
-
9
before(:each) { sign_in user }
-
-
1
describe "GET site" do
-
1
before(:each) do
-
2
user = 'iLab'
-
2
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
2
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
2
get :show, id: site.id, format: 'rss', collection_id: collection.id
-
end
-
-
2
it { expect(response).to be_success }
-
1
it "should response RSS" do
-
1
expect(response.content_type).to eq 'application/rss+xml'
-
end
-
end
-
-
-
1
describe "GET all sites " do
-
1
before(:each) do
-
2
user = 'iLab'
-
2
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
2
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
end
-
-
1
it "should return one site in the collection" do
-
1
get :index, format: 'json', limit: 1, offset: 1, collection_id: collection.id
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["sites"].length).to eq(1)
-
end
-
-
1
it "should return two sites in the collection" do
-
1
get :index, format: 'json', limit: 2, offset: 0, collection_id: collection.id
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["sites"].length).to eq(2)
-
end
-
-
end
-
-
1
describe "Create sites" do
-
1
before(:each) do
-
1
user = 'iLab'
-
1
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
1
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
end
-
-
1
it "should save site in the collection" do
-
1
post :create, format: 'json', name: 'Hello', lat: 12.618897, lng: 104.765625, collection_id: collection.id, properties: {}, phone_number: user.phone_number
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["site"]["name"]).to eq("Hello")
-
1
expect(json["site"]["lat"]).to eq("12.618897")
-
1
expect(json["site"]["lng"]).to eq("104.765625")
-
1
expect(json["site"]["collection_id"]).to eq(collection.id)
-
1
expect(json["site"]["properties"]).to eq({})
-
end
-
end
-
-
1
describe "Update sites" do
-
1
before(:each) do
-
1
user = 'iLab'
-
1
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
1
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
end
-
-
1
it "should save site in the collection" do
-
1
put :update, format: 'json', id: site.id, name: 'Hello', lat: 12.618897, lng: 104.765625, collection_id: collection.id, properties: {}, phone_number: user.phone_number
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["site"]["name"]).to eq("Hello")
-
1
expect(json["site"]["lat"]).to eq("12.618897")
-
1
expect(json["site"]["lng"]).to eq("104.765625")
-
1
expect(json["site"]["collection_id"]).to eq(collection.id)
-
1
expect(json["site"]["properties"]).to eq({})
-
end
-
end
-
-
1
describe "Delete sites" do
-
1
before(:each) do
-
2
user = 'iLab'
-
2
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
2
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
end
-
-
1
it "should have two sites befor delete" do
-
1
expect(collection.sites.length).to eq(2)
-
end
-
-
1
it "should delete site in the collection" do
-
1
delete :destroy, format: 'json', id: site.id, collection_id: collection.id
-
1
expect(response).to be_success
-
1
expect(collection.sites.length).to eq(1)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Api::V1::SitesController do
-
1
include Devise::TestHelpers
-
10
let!(:user) { User.make }
-
10
let!(:collection) { user.create_collection(Collection.make_unsaved) }
-
10
let!(:layer) { collection.layers.make }
-
10
let!(:text) { layer.text_fields.make :code => 'text'}
-
10
let!(:numeric) { layer.numeric_fields.make :code => 'numeric' }
-
10
let!(:yes_no) { layer.yes_no_fields.make :code => 'yes_no'}
-
10
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
10
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
1
config_hierarchy = [{ id: 'dad', name: 'Dad', sub: [{id: 'son', name: 'Son'}, {id: 'bro', name: 'Bro'}]}]
-
10
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
10
let!(:site_ref) { layer.site_fields.make :code => 'site' }
-
10
let!(:date) { layer.date_fields.make :code => 'date' }
-
10
let!(:director) { layer.user_fields.make :code => 'user'}
-
-
10
let!(:site1) { collection.sites.make }
-
10
let!(:site2) { collection.sites.make }
-
10
let!(:collection1) { user.create_collection(Collection.make_unsaved) }
-
-
10
before(:each) { sign_in user }
-
1
describe "GET sites" do
-
1
before(:each) do
-
2
user = 'iLab'
-
2
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
2
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
# get :show, id: site.id, format: 'json'
-
end
-
-
1
it "should return one site in the collection" do
-
1
get :index, format: 'json', limit: 1, offset: 1, collection_id: collection.id
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["sites"].length).to eq(1)
-
end
-
-
1
it "should return two sites in the collection" do
-
1
get :index, format: 'json', limit: 2, offset: 0, collection_id: collection.id
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["sites"].length).to eq(2)
-
end
-
end
-
-
1
describe "Create sites" do
-
1
before(:each) do
-
6
user = 'iLab'
-
6
pw = '1c4989610bce6c4879c01bb65a45ad43'
-
6
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
-
end
-
-
1
before(:each) do
-
6
site1.device_id = 'dv1'
-
6
site1.external_id = '1'
-
6
site1.save
-
-
6
site2.device_id = 'dv1'
-
6
site2.external_id = '2'
-
6
site2.save
-
end
-
-
1
it "should save site in the collection1" do
-
1
post :create, collection_id: collection1.id, site: { name: 'Hello', device_id: 'dv1', external_id: '1', lat: 12.618897, lng: 104.765625, properties: {}}
-
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq("Hello")
-
1
expect(json["lat"]).to eq("12.618897")
-
1
expect(json["lng"]).to eq("104.765625")
-
1
expect(json["collection_id"]).to eq(collection1.id)
-
1
expect(json["properties"]).to eq({})
-
end
-
-
1
it "should save site in the collection" do
-
1
post :create, collection_id: collection.id, site: { name: 'Hello', lat: 12.618897, lng: 104.765625, properties: {"#{text.id}"=> 'test1', "#{numeric.id}"=> 10}}
-
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq("Hello")
-
1
expect(json["lat"]).to eq("12.618897")
-
1
expect(json["lng"]).to eq("104.765625")
-
1
expect(json["collection_id"]).to eq(collection.id)
-
1
expect(json["properties"]).to eq({"#{text.id}"=> 'test1', "#{numeric.id}"=> 10})
-
end
-
-
1
context 'when device_id and external_id valid' do
-
1
it "should save site in the collection" do
-
1
post :create, collection_id: collection.id, site: { name: 'Hello', lat: 12.618897, lng: 104.765625, device_id: 'dv1', external_id: 3, properties: {"#{text.id}"=> 'test1', "#{numeric.id}"=> 10}}
-
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq("Hello")
-
1
expect(json["lat"]).to eq("12.618897")
-
1
expect(json["lng"]).to eq("104.765625")
-
1
expect(json["device_id"]).to eq("dv1")
-
1
expect(json["external_id"]).to eq("3")
-
1
expect(json["collection_id"]).to eq(collection.id)
-
1
expect(json["properties"]).to eq({"#{text.id}"=> 'test1', "#{numeric.id}"=> 10})
-
end
-
end
-
-
1
context 'when external_id valid' do
-
1
it "should save site in the collection" do
-
1
post :create, collection_id: collection.id, site: { name: 'Bonjour', lat: 12.618897, lng: 104.765625, device_id: 'dv1', external_id: 3, properties: {"#{text.id}"=> 'test2', "#{numeric.id}"=> 20}}
-
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq("Bonjour")
-
1
expect(json["lat"]).to eq("12.618897")
-
1
expect(json["lng"]).to eq("104.765625")
-
1
expect(json["device_id"]).to eq("dv1")
-
1
expect(json["external_id"]).to eq("3")
-
1
expect(json["collection_id"]).to eq(collection.id)
-
1
expect(json["properties"]).to eq({"#{text.id}"=> 'test2', "#{numeric.id}"=> 20})
-
end
-
end
-
-
1
context 'when device_id valid' do
-
1
it "should save site in the collection" do
-
1
post :create, collection_id: collection.id, site: { name: 'Bonjour', lat: 12.618897, lng: 104.765625, device_id: 'dv2', external_id: 1, properties: {"#{text.id}"=> 'test2', "#{numeric.id}"=> 20}}
-
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq("Bonjour")
-
1
expect(json["lat"]).to eq("12.618897")
-
1
expect(json["lng"]).to eq("104.765625")
-
1
expect(json["device_id"]).to eq("dv2")
-
1
expect(json["external_id"]).to eq("1")
-
1
expect(json["collection_id"]).to eq(collection.id)
-
1
expect(json["properties"]).to eq({"#{text.id}"=> 'test2', "#{numeric.id}"=> 20})
-
end
-
end
-
-
1
context 'when external_id is already exist' do
-
1
it "should update site in the collection" do
-
1
post :create, collection_id: collection.id, site: { name: 'Thyda', lat: 12.618897, lng: 104.765625, device_id: 'dv1', external_id: '1', properties: {"#{text.id}"=> 'test2', "#{numeric.id}"=> 20}}
-
-
1
expect(response).to be_success
-
1
expect(collection.sites.count).to eq(2)
-
1
expect(collection.sites[0].name).to eq("Thyda")
-
end
-
end
-
-
end
-
-
1
describe "Update sites" do
-
1
before(:each) do
-
1
site1.device_id = 'dv1'
-
1
site1.external_id = '1'
-
1
site1.save
-
-
1
site2.device_id = 'dv1'
-
1
site2.external_id = '2'
-
1
site2.save
-
end
-
-
1
it "should update site" do
-
1
put :update, collection_id: collection.id, id: site1.id, site: {name: 'Thyda', lat: 12.618897, lng: 104.765625, device_id: 'dv1', external_id: '2', properties: {"#{text.id}"=> 'test2', "#{numeric.id}"=> 40}}
-
-
1
expect(response).to be_success
-
1
expect(collection.sites[0].name).to eq("Thyda")
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe ChannelsAccessesController do
-
-
end
-
1
require 'spec_helper'
-
-
1
describe CollectionsController, :type => :controller do
-
1
include Devise::TestHelpers
-
1
render_views
-
15
let!(:user) { User.make }
-
15
let!(:collection) { user.create_collection(Collection.make public: false) }
-
-
15
before(:each) {sign_in user}
-
-
-
1
it "should generate error description form preprocessed hierarchy list" do
-
1
hierarchy_csv = [
-
{:order=>1, :error=>"Wrong format.", :error_description=>"Invalid column number"},
-
{:order=>2, :id=>"2", :name=>"dad", :sub=>[{:order=>3, :id=>"3", :name=>"son"}]} ]
-
-
1
res = CollectionsController.generate_error_description_list(hierarchy_csv)
-
-
1
expect(res).to eq("Error: Wrong format. Invalid column number in line 1.")
-
end
-
-
1
it "should generate error description form invalid hierarchy list" do
-
1
hierarchy_csv = [{:error=>"Illegal quoting in line 3."}]
-
-
1
res = CollectionsController.generate_error_description_list(hierarchy_csv)
-
-
1
expect(res).to eq("Error: Illegal quoting in line 3.")
-
end
-
-
1
it "should generate error description html form invalid hierarchy list with >1 errors" do
-
1
hierarchy_csv = [
-
{:order=>1, :error=>"Wrong format.", :error_description=>"Invalid column number"},
-
{:order=>2, :error=>"Wrong format.", :error_description=>"Invalid column number"} ]
-
-
-
1
res = CollectionsController.generate_error_description_list(hierarchy_csv)
-
-
1
expect(res).to eq("Error: Wrong format. Invalid column number in line 1.<br/>Error: Wrong format. Invalid column number in line 2.")
-
end
-
-
1
it "should not throw error when calling unload_current_snapshot and no snapshot is set" do
-
1
post :unload_current_snapshot, collection_id: collection.id
-
1
assert_nil flash[:notice]
-
1
assert_redirected_to collection_url(collection.id)
-
end
-
-
1
describe "get ES resutls" do
-
1
before(:each) do
-
2
layer = collection.layers.make
-
-
2
text = layer.text_fields.make :code => 'text'
-
2
numeric = layer.numeric_fields.make :code => 'numeric'
-
-
2
@site1 = collection.sites.make :name => "site1", :properties => {text.es_code => 'foo', numeric.es_code => 1 }
-
2
@site2 = collection.sites.make :name => "osite2", :properties => {text.es_code => 'bar', numeric.es_code => 2 }
-
end
-
-
1
it "should get json of all field names and codes in a collection" do
-
1
get :sites_by_term, collection_id: collection.id, format: 'json'
-
-
1
json = JSON.parse response.body
-
1
expect(json.length).to eq(2)
-
1
expect(json[0]["id"]).to eq(@site2.id)
-
1
expect(json[0]["name"]).to eq(@site2.name)
-
1
expect(json[0]["value"]).to eq(@site2.name)
-
1
expect(json[1]["id"]).to eq(@site1.id)
-
1
expect(json[1]["name"]).to eq(@site1.name)
-
1
expect(json[1]["value"]).to eq(@site1.name)
-
end
-
-
1
it "should filter by name in a collection" do
-
1
get :sites_by_term, collection_id: collection.id, format: 'json', term: "o"
-
-
1
json = JSON.parse response.body
-
1
expect(json.length).to eq(1)
-
1
expect(json[0]["id"]).to eq(@site2.id)
-
1
expect(json[0]["name"]).to eq(@site2.name)
-
1
expect(json[0]["value"]).to eq(@site2.name)
-
end
-
end
-
-
1
describe "Permissions" do
-
4
let!(:public_collection) { user.create_collection(Collection.make public: true) }
-
4
let!(:not_member) { User.make }
-
4
let!(:member) { User.make }
-
-
1
before(:each) do
-
3
sign_out user
-
3
collection.memberships.create! :user_id => member.id, admin: false
-
3
public_collection.memberships.create! :user_id => member.id, admin: false
-
end
-
-
1
it 'should return 404 in delete if user tries to delete a collection of which he is not member' do
-
1
sign_in not_member
-
1
delete :destroy, id: collection.id
-
1
expect(response.status).to eq(404)
-
1
delete :destroy, id: public_collection.id
-
1
expect(response.status).to eq(404)
-
end
-
-
1
it 'should return forbidden on delete if user is not collection admin' do
-
1
sign_in member
-
1
delete :destroy, id: collection.id
-
1
expect(response.status).to eq(403)
-
1
delete :destroy, id: public_collection.id
-
1
expect(response.status).to eq(403)
-
end
-
-
1
it 'should return forbidden on create_snapshot if user is not collection admin' do
-
1
sign_in member
-
1
post :create_snapshot, collection_id: public_collection.id, snapshot: {name: 'my snapshot'}
-
1
expect(response.status).to eq(403)
-
1
post :create_snapshot, collection_id: collection.id, snapshot: {name: 'my snapshot'}
-
1
expect(response.status).to eq(403)
-
end
-
-
end
-
-
1
describe "analytic" do
-
1
it 'should changed user.collection_count by 1' do
-
1
expect{
-
1
post :create, collection: { name: 'collection_1', icon: 'default'}
-
}.to change{
-
2
u = User.find user
-
2
u.collection_count
-
}.from(0).to(1)
-
-
end
-
end
-
-
1
describe "public access" do
-
3
let!(:public_collection) { user.create_collection(Collection.make public: true) }
-
3
before(:each) { sign_out :user }
-
-
1
it 'should get index as guest' do
-
1
get :index, collection_id: public_collection.id
-
1
expect(response).to be_success
-
end
-
-
1
it 'should get index if collection_id is not passed' do
-
1
get :index
-
1
expect(response).to be_success
-
end
-
end
-
-
1
describe "sites info" do
-
1
it "gets when all have location" do
-
1
collection.sites.make
-
1
collection.sites.make
-
-
1
get :sites_info, collection_id: collection.id
-
-
1
info = JSON.parse response.body
-
1
expect(info["total"]).to eq(2)
-
1
expect(info["no_location"]).to be_falsey
-
end
-
-
1
it "gets when some have no location" do
-
1
collection.sites.make
-
1
collection.sites.make
-
1
collection.sites.make lat: nil, lng: nil
-
-
1
get :sites_info, collection_id: collection.id
-
-
1
info = JSON.parse response.body
-
1
expect(info["total"]).to eq(3)
-
1
expect(info["no_location"]).to be_truthy
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe GatewaysController, :type => :controller do
-
1
include Devise::TestHelpers
-
1
render_views
-
-
3
let!(:user) { User.make }
-
3
let!(:gateway) { user.channels.make name: 'default', basic_setup: true, ticket_code: '2222', is_enable: false }
-
-
3
before(:each) {sign_in user}
-
1
it "should turn on gateway" do
-
1
post :status, id: gateway.id, status: true, format: 'json'
-
1
expect(Channel.find(gateway).is_enable).to eq(true)
-
end
-
-
1
describe 'analytic' do
-
1
it 'should changed user.gateway_count by 1' do
-
1
expect {
-
1
post :create, gateway: { name: 'default1', basic_setup: true, ticket_code: '2222', is_enable: true, user_id: user.id }
-
}.to change{
-
2
u = User.find user
-
2
u.gateway_count
-
}.from(0).to(1)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe ImportWizardsController, :type => :controller do
-
1
include Devise::TestHelpers
-
1
render_views
-
-
2
let!(:user) { User.make }
-
2
let!(:collection) { user.create_collection(Collection.make) }
-
-
2
before(:each) {sign_in user}
-
2
let!(:user2) { User.make }
-
2
let!(:membership) { collection.memberships.create! :user_id => user2.id }
-
-
1
it "should not allow to create a new field to a non-admin user" do
-
1
sign_out user
-
1
membership.set_layer_access :verb => :read, :access => true
-
1
membership.set_layer_access :verb => :write, :access => true
-
1
sign_in user2
-
-
1
uploaded_file = Rack::Test::UploadedFile.new(Rails.root.join('spec/fixtures/csv_test.csv'), "text/csv")
-
1
post :upload_csv, collection_id: collection.id, file: uploaded_file, format: 'csv'
-
-
1
specs = {
-
'0' => {name: 'Name', usage: 'name'},
-
'1' => {name: 'Lat', usage: 'lat'},
-
'2' => {name: 'Lon', usage: 'lng'},
-
'3' => {name: 'Beds', usage: 'new_field', kind: 'numeric', code: 'beds', label: 'The beds'},
-
}
-
1
post :execute, collection_id: collection.id, columns: specs
-
1
expect(response.response_code).to eq(401)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe LayersController, :type => :controller do
-
1
include Devise::TestHelpers
-
1
render_views
-
-
4
let!(:user) { User.make }
-
4
let!(:collection) { user.create_collection(Collection.make) }
-
4
let!(:layer) {Layer.make collection: collection, user: user}
-
4
let!(:layer2) {Layer.make collection: collection, user: user}
-
4
let!(:numeric) {layer.numeric_fields.make }
-
4
let!(:threshold) {collection.thresholds.make conditions: [ "field" => numeric.es_code, op: :lt, value: '10' ]}
-
-
4
before(:each) {sign_in user}
-
-
1
it "should update field.layer_id" do
-
-
1
expect(layer.fields.count).to eq(1)
-
1
json_layer = {id: layer.id, name: layer.name, ord: layer.ord, public: layer.public, fields_attributes: {:"0" => {code: numeric.code, id: numeric.id, kind: numeric.kind, name: numeric.name, ord: numeric.ord, layer_id: layer2.id}}}
-
-
1
post :update, {layer: json_layer, collection_id: collection.id, id: layer.id}
-
-
1
expect(layer.fields.count).to eq(0)
-
1
expect(layer2.fields.count).to eq(1)
-
1
expect(layer2.fields.first.name).to eq(numeric.name)
-
-
1
histories = FieldHistory.where :field_id => numeric.id
-
-
1
expect(histories.count).to eq(2)
-
-
1
expect(histories.first.layer_id).to eq(layer.id)
-
1
expect(histories.first.valid_to).not_to be_nil
-
-
1
expect(histories.last.valid_to).to be_nil
-
1
expect(histories.last.layer_id).to eq(layer2.id)
-
-
end
-
-
1
describe 'analytic' do
-
1
it 'should changed user.layer_count by 1' do
-
1
expect {
-
1
post :create, layer: { name: 'layer_01', fields: [], ord: 1}, collection_id: collection.id
-
}.to change{
-
2
u = User.find user
-
2
u.layer_count
-
}.from(0).to(1)
-
end
-
end
-
-
1
describe 'create layer' do
-
1
it "should save layer" do
-
1
config_locations = {"0"=>{"code"=>"257", "name"=>"Achar Leak", "latitude"=>"12.7237", "longitude"=>"104.893997"}, "1"=>{"code"=>"1574", "name"=>"Aekakpheap", "latitude"=>"13.8067", "longitude"=>"104.958"}, "2"=>{"code"=>"600", "name"=>"Ampeng", "latitude"=>"10.4928", "longitude"=>"104.387001"}, "3"=>{"code"=>"736", "name"=>"Ampil", "latitude"=>"11.4571", "longitude"=>"105.811996"}, "4"=>{"code"=>"391", "name"=>"Ampil Chas", "latitude"=>"14.233", "longitude"=>"103.129997"}, "5"=>{"code"=>"1486", "name"=>"Ampil Leu", "latitude"=>"12.0016", "longitude"=>"105.444"}, "6"=>{"code"=>"1170", "name"=>"Ampil Tuek", "latitude"=>"11.2693", "longitude"=>"105.272003"}, "7"=>{"code"=>"528", "name"=>"Ampov Prey", "latitude"=>"10.8859", "longitude"=>"105.288002"}, "8"=>{"code"=>"196", "name"=>"Andong Pir", "latitude"=>"13.3827", "longitude"=>"102.364998"}, "9"=>{"code"=>"472", "name"=>"Andoung", "latitude"=>"11.2344", "longitude"=>"105.367996"}, "10"=>{"code"=>"1300", "name"=>"Andoung Chek", "latitude"=>"12.1303", "longitude"=>"104.622002"}, "11"=>{"code"=>"1360", "name"=>"Andoung Chraoh", "latitude"=>"12.013", "longitude"=>"105.429001"}, "12"=>{"code"=>"1770", "name"=>"Andoung Kraloeng", "latitude"=>"12.3183", "longitude"=>"107.087997"}, "13"=>{"code"=>"444", "name"=>"Andoung Pou", "latitude"=>"13.8035", "longitude"=>"104.795998"}, "14"=>{"code"=>"145", "name"=>"Andoung Pring", "latitude"=>"13.0599", "longitude"=>"103.158997"}, "15"=>{"code"=>"1267", "name"=>"Andoung Rovieng", "latitude"=>"12.362", "longitude"=>"104.445"}, "16"=>{"code"=>"454", "name"=>"Andoung S'at", "latitude"=>"11.6215", "longitude"=>"105.746002"}, "17"=>{"code"=>"179", "name"=>"Andoung Taa Pech", "latitude"=>"12.1479", "longitude"=>"105.246002"}, "18"=>{"code"=>"1239", "name"=>"Andoung Tuek", "latitude"=>"11.1864", "longitude"=>"103.475998"}, "19"=>{"code"=>"1057", "name"=>"Angk", "latitude"=>"10.6126", "longitude"=>"104.245003"}, "20"=>{"code"=>"1017", "name"=>"Angk Doun Pis", "latitude"=>"11.3294", "longitude"=>"104.624001"}, "21"=>{"code"=>"823", "name"=>"Angk Kabbas", "latitude"=>"11.1616", "longitude"=>"105.713997"}, "22"=>{"code"=>"672", "name"=>"Angk Khcheay Khang Cheung", "latitude"=>"10.8337", "longitude"=>"104.586998"}, "23"=>{"code"=>"289", "name"=>"Angk Khloam", "latitude"=>"13.0342", "longitude"=>"104.514"}, "24"=>{"code"=>"1134", "name"=>"Angk Klaeu", "latitude"=>"11.353", "longitude"=>"104.777"}, "25"=>{"code"=>"1686", "name"=>"Angk Metrei", "latitude"=>"11.4318", "longitude"=>"104.658997"}, "26"=>{"code"=>"1660", "name"=>"Angk Neareay", "latitude"=>"11.0179", "longitude"=>"104.725998"}, "27"=>{"code"=>"907", "name"=>"Angk Reang", "latitude"=>"11.112", "longitude"=>"104.720001"}, "28"=>{"code"=>"1003", "name"=>"Angk Romeas", "latitude"=>"11.3236", "longitude"=>"104.705002"}, "29"=>{"code"=>"1619", "name"=>"Angk Rumduol", "latitude"=>"10.806", "longitude"=>"104.660004"}, "30"=>{"code"=>"1672", "name"=>"Angk Serei", "latitude"=>"11.4694", "longitude"=>"104.547997"}, "31"=>{"code"=>"1710", "name"=>"Angk Snuol Ti Pir", "latitude"=>"11.505", "longitude"=>"104.719002"}, "32"=>{"code"=>"1061", "name"=>"Angk Ta Mau", "latitude"=>"11.4711", "longitude"=>"104.456001"}, "33"=>{"code"=>"1461", "name"=>"Angk Ta Saom", "latitude"=>"11.0091", "longitude"=>"104.677002"}, "34"=>{"code"=>"949", "name"=>"Angk Tnaot Khang Kaeut", "latitude"=>"10.9924", "longitude"=>"104.670998"}, "35"=>{"code"=>"1052", "name"=>"Angk Tonloab", "latitude"=>"11.5357", "longitude"=>"104.598999"}, "36"=>{"code"=>"964", "name"=>"Angk Trav", "latitude"=>"11.0426", "longitude"=>"104.575996"}, "37"=>{"code"=>"1503", "name"=>"Angkor Ban Ti Bei", "latitude"=>"11.9463", "longitude"=>"105.227997"}, "38"=>{"code"=>"83", "name"=>"Angkor Ban Ti Buon", "latitude"=>"11.9482", "longitude"=>"105.222"}, "39"=>{"code"=>"1656", "name"=>"Angkor Phdiek", "latitude"=>"11.1437", "longitude"=>"104.759003"}, "40"=>{"code"=>"513", "name"=>"Angkor Sar", "latitude"=>"11.249", "longitude"=>"105.626999"}, "41"=>{"code"=>"537", "name"=>"Angkor Tret", "latitude"=>"11.534", "longitude"=>"105.450996"}, "42"=>{"code"=>"461", "name"=>"Angkrong", "latitude"=>"11.0167", "longitude"=>"105.532997"}, "43"=>{"code"=>"30", "name"=>"Anglong Svay", "latitude"=>"13.6231", "longitude"=>"102.683998"}, "44"=>{"code"=>"1046", "name"=>"Angvae", "latitude"=>"11.3617", "longitude"=>"104.526001"}, "45"=>{"code"=>"304", "name"=>"Anhchanh", "latitude"=>"12.4807", "longitude"=>"106.125999"}, "46"=>{"code"=>"1500", "name"=>"Anlok Kaong", "latitude"=>"12.9539", "longitude"=>"103.149002"}, "47"=>{"code"=>"806", "name"=>"Anlong Chrey", "latitude"=>"13.7643", "longitude"=>"105.661003"}, "48"=>{"code"=>"1694", "name"=>"Anlong Kngan", "latitude"=>"11.6185", "longitude"=>"104.850998"}, "49"=>{"code"=>"1055", "name"=>"Anlong Meakprang", "latitude"=>"10.7021", "longitude"=>"104.177002"}, "50"=>{"code"=>"703", "name"=>"Anlong Pir", "latitude"=>"13.3068", "longitude"=>"104.042999"}, "51"=>{"code"=>"334", "name"=>"Anlong Preah Kou", "latitude"=>"12.6537", "longitude"=>"105.999001"}, "52"=>{"code"=>"1089", "name"=>"Anlong Romiet Khang Cheung", "latitude"=>"11.4232", "longitude"=>"104.810997"}, "53"=>{"code"=>"1617", "name"=>"Anlong Samnar", "latitude"=>"13.0663", "longitude"=>"104.293999"}, "54"=>{"code"=>"1022", "name"=>"Anlong Sangkae", "latitude"=>"11.665", "longitude"=>"104.125"}, "55"=>{"code"=>"1167", "name"=>"Anlong Sant", "latitude"=>"11.082", "longitude"=>"105.064003"}, "56"=>{"code"=>"584", "name"=>"Anlong Sar", "latitude"=>"11.8163", "longitude"=>"105.371002"}, "57"=>{"code"=>"734", "name"=>"Anlong Spean", "latitude"=>"11.1809", "longitude"=>"105.787003"}, "58"=>{"code"=>"33", "name"=>"Anlong Svay", "latitude"=>"13.7008", "longitude"=>"102.862999"}, "59"=>{"code"=>"342", "name"=>"Anlong Ta Uor", "latitude"=>"13.2307", "longitude"=>"103.661003"}, "60"=>{"code"=>"768", "name"=>"Anlong Thum", "latitude"=>"13.536", "longitude"=>"104.174004"}, "61"=>{"code"=>"840", "name"=>"Anlong Tien", "latitude"=>"10.846", "longitude"=>"104.996002"}, "62"=>{"code"=>"552", "name"=>"Anlong Trea", "latitude"=>"11.4558", "longitude"=>"105.282997"}, "63"=>{"code"=>"1246", "name"=>"Anlong Vak", "latitude"=>"11.5627", "longitude"=>"103.135002"}, "64"=>{"code"=>"602", "name"=>"Anlong Vil", "latitude"=>"12.6176", "longitude"=>"104.004997"}, "65"=>{"code"=>"459", "name"=>"Ansaong", "latitude"=>"11.1238", "longitude"=>"105.544998"}, "66"=>{"code"=>"918", "name"=>"Ba Tang", "latitude"=>"13.5406", "longitude"=>"107.024002"}, "67"=>{"code"=>"1448", "name"=>"Bacham", "latitude"=>"11.2404", "longitude"=>"104.816002"}, "68"=>{"code"=>"166", "name"=>"Baek Anlung", "latitude"=>"12.3592", "longitude"=>"105.596001"}, "69"=>{"code"=>"1194", "name"=>"Baek Chan", "latitude"=>"11.5065", "longitude"=>"104.753998"}, "70"=>{"code"=>"1218", "name"=>"Baek Thlang", "latitude"=>"11.7331", "longitude"=>"104.733002"}, "71"=>{"code"=>"757", "name"=>"Bak Dai", "latitude"=>"10.8966", "longitude"=>"105.039001"}, "72"=>{"code"=>"1145", "name"=>"Bak Dav Kraom", "latitude"=>"11.5965", "longitude"=>"105.114998"}, "73"=>{"code"=>"446", "name"=>"Bak Kam", "latitude"=>"13.7826", "longitude"=>"104.852997"}, "74"=>{"code"=>"1572", "name"=>"Bak Kdaong", "latitude"=>"13.3665", "longitude"=>"105.116997"}, "75"=>{"code"=>"1723", "name"=>"Bak Khlang Mouy", "latitude"=>"11.5656", "longitude"=>"102.959"}, "76"=>{"code"=>"1249", "name"=>"Bak Khlang Pir", "latitude"=>"11.5654", "longitude"=>"102.959999"}, "77"=>{"code"=>"206", "name"=>"Bak Prea", "latitude"=>"13.3129", "longitude"=>"103.406998"}, "78"=>{"code"=>"566", "name"=>"Bak Roteh", "latitude"=>"12.5325", "longitude"=>"103.93"}, "79"=>{"code"=>"223", "name"=>"Bak Sna Kraom", "latitude"=>"12.5116", "longitude"=>"105.285004"}, "80"=>{"code"=>"266", "name"=>"Bak Srei", "latitude"=>"12.8836", "longitude"=>"105.071999"}, "81"=>{"code"=>"1349", "name"=>"Bakham", "latitude"=>"12.1841", "longitude"=>"105.129997"}, "82"=>{"code"=>"189", "name"=>"Balang Khang Lech", "latitude"=>"12.6954", "longitude"=>"104.901001"}, "83"=>{"code"=>"34", "name"=>"Baliley", "latitude"=>"13.6622", "longitude"=>"102.578003"}, "84"=>{"code"=>"61", "name"=>"Ballangk", "latitude"=>"13.4695", "longitude"=>"102.733002"}, "85"=>{"code"=>"1638", "name"=>"Ban Mai", "latitude"=>"13.5468", "longitude"=>"106.088997"}, "86"=>{"code"=>"1658", "name"=>"Ban Phang", "latitude"=>"13.9723", "longitude"=>"106.827003"}, "87"=>{"code"=>"942", "name"=>"Ban Pong", "latitude"=>"13.9701", "longitude"=>"106.834"}, "88"=>{"code"=>"1256", "name"=>"Ban Tiet", "latitude"=>"11.1348", "longitude"=>"103.754997"}, "89"=>{"code"=>"1395", "name"=>"Banan", "latitude"=>"12.9492", "longitude"=>"103.148003"}, "90"=>{"code"=>"1555", "name"=>"Banang", "latitude"=>"12.8848", "longitude"=>"102.972"}, "91"=>{"code"=>"2", "name"=>"Bang Bat Kaeut", "latitude"=>"13.5182", "longitude"=>"102.992996"}, "92"=>{"code"=>"1430", "name"=>"Bangaek", "latitude"=>"11.1016", "longitude"=>"105.223999"}, "93"=>{"code"=>"129", "name"=>"Bangkov", "latitude"=>"11.7858", "longitude"=>"106.123001"}, "94"=>{"code"=>"1113", "name"=>"Banla S'et", "latitude"=>"11.6072", "longitude"=>"104.873001"}, "95"=>{"code"=>"399", "name"=>"Bansay Reak", "latitude"=>"14.2334", "longitude"=>"103.464996"}, "96"=>{"code"=>"182", "name"=>"Banteay", "latitude"=>"11.8475", "longitude"=>"105.197998"}, "97"=>{"code"=>"704", "name"=>"Banteay Chas", "latitude"=>"13.3567", "longitude"=>"103.874001"}, "98"=>{"code"=>"43", "name"=>"Banteay Chhmar Tboung", "latitude"=>"14.0636", "longitude"=>"103.107002"}, "99"=>{"code"=>"1498", "name"=>"Banteay Mean Rit", "latitude"=>"13.986", "longitude"=>"102.865997"}, "100"=>{"code"=>"1", "name"=>"Banteay Neang", "latitude"=>"13.5105", "longitude"=>"103.019997"}, "101"=>{"code"=>"633", "name"=>"Banteay Srei", "latitude"=>"13.5881", "longitude"=>"103.962997"}, "102"=>{"code"=>"250", "name"=>"Banteay Stoung", "latitude"=>"12.9285", "longitude"=>"104.649002"}, "103"=>{"code"=>"57", "name"=>"Banteay Ti Pir", "latitude"=>"13.5591", "longitude"=>"102.487"}, "104"=>{"code"=>"1540", "name"=>"Banteay Yumreach", "latitude"=>"12.5254", "longitude"=>"105.100998"}, "105"=>{"code"=>"1562", "name"=>"Baoh Pou", "latitude"=>"13.0606", "longitude"=>"103.211998"}, "106"=>{"code"=>"547", "name"=>"Baray Lech", "latitude"=>"11.4622", "longitude"=>"105.347"}, "107"=>{"code"=>"1406", "name"=>"Baray Touch", "latitude"=>"12.3929", "longitude"=>"105.085999"}, "108"=>{"code"=>"1468", "name"=>"Barku", "latitude"=>"11.4087", "longitude"=>"104.830002"}, "109"=>{"code"=>"344", "name"=>"Basaet", "latitude"=>"13.1152", "longitude"=>"103.308998"}, "110"=>{"code"=>"1614", "name"=>"Bat", "latitude"=>"13.7313", "longitude"=>"103.671997"}, "111"=>{"code"=>"1025", "name"=>"Bat Doeng", "latitude"=>"11.6811", "longitude"=>"104.702003"}, "112"=>{"code"=>"361", "name"=>"Bat Kokir", "latitude"=>"10.5852", "longitude"=>"103.766998"}, "113"=>{"code"=>"96", "name"=>"Bat Srei Totueng", "latitude"=>"11.8383", "longitude"=>"105.393997"}, "114"=>{"code"=>"1324", "name"=>"Batheay", "latitude"=>"11.988", "longitude"=>"104.945999"}, "115"=>{"code"=>"478", "name"=>"Bati", "latitude"=>"11.3269", "longitude"=>"105.296997"}, "116"=>{"code"=>"1722", "name"=>"Battachi", "latitude"=>"11.4534", "longitude"=>"104.934998"}, "117"=>{"code"=>"1373", "name"=>"Bavel Muoy", "latitude"=>"13.2535", "longitude"=>"102.877998"}, "118"=>{"code"=>"1499", "name"=>"Bay Damram", "latitude"=>"12.9939", "longitude"=>"103.164001"}, "119"=>{"code"=>"455", "name"=>"Bayab", "latitude"=>"11.6458", "longitude"=>"105.5"}, "120"=>{"code"=>"1750", "name"=>"Bei Maetr", "latitude"=>"12.1161", "longitude"=>"105.686996"}, "121"=>{"code"=>"503", "name"=>"Beng", "latitude"=>"11.0341", "longitude"=>"105.566002"}, "122"=>{"code"=>"492", "name"=>"Beng Sat", "latitude"=>"13.3048", "longitude"=>"102.366997"}, "123"=>{"code"=>"1281", "name"=>"Ber", "latitude"=>"12.2512", "longitude"=>"104.666"}, "124"=>{"code"=>"689", "name"=>"Boeng", "latitude"=>"13.3654", "longitude"=>"103.780998"}, "125"=>{"code"=>"1608", "name"=>"Boeng Chak", "latitude"=>"12.6202", "longitude"=>"104.011002"}, "126"=>{"code"=>"588", "name"=>"Boeng Chhuk", "latitude"=>"12.5906", "longitude"=>"103.727997"}, "127"=>{"code"=>"583", "name"=>"Boeng Choar", "latitude"=>"11.7389", "longitude"=>"105.366997"}, "128"=>{"code"=>"560", "name"=>"Boeng Daol", "latitude"=>"11.0574", "longitude"=>"105.338997"}, "129"=>{"code"=>"1128", "name"=>"Boeng Kaek", "latitude"=>"11.3584", "longitude"=>"104.853996"}, "130"=>{"code"=>"559", "name"=>"Boeng Kampot", "latitude"=>"11.0099", "longitude"=>"105.380997"}, "131"=>{"code"=>"226", "name"=>"Boeng Kandal", "latitude"=>"12.427", "longitude"=>"105.113998"}, "132"=>{"code"=>"587", "name"=>"Boeng Khnar", "latitude"=>"12.6323", "longitude"=>"103.732002"}, "133"=>{"code"=>"1090", "name"=>"Boeng Khyang", "latitude"=>"11.3599", "longitude"=>"104.875"}, "134"=>{"code"=>"1176", "name"=>"Boeng Krum Kraom", "latitude"=>"11.4738", "longitude"=>"105.167"}, "135"=>{"code"=>"576", "name"=>"Boeng Laeng", "latitude"=>"11.8086", "longitude"=>"105.334"}, "136"=>{"code"=>"1313", "name"=>"Boeng Leach", "latitude"=>"11.8866", "longitude"=>"104.690002"}, "137"=>{"code"=>"282", "name"=>"Boeng Lvea", "latitude"=>"12.5404", "longitude"=>"105.153999"}, "138"=>{"code"=>"477", "name"=>"Boeng Phsaot", "latitude"=>"11.3555", "longitude"=>"105.271004"}, "139"=>{"code"=>"1252", "name"=>"Boeng Preav", "latitude"=>"11.0924", "longitude"=>"103.779999"}, "140"=>{"code"=>"100", "name"=>"Boeng Pring", "latitude"=>"13.3615", "longitude"=>"103.039001"}, "141"=>{"code"=>"987", "name"=>"Boeng Ta Mom", "latitude"=>"11.1321", "longitude"=>"104.468002"}, "142"=>{"code"=>"357", "name"=>"Boeng Ta Prum", "latitude"=>"10.5704", "longitude"=>"103.779999"}, "143"=>{"code"=>"1447", "name"=>"Boeng Thnong", "latitude"=>"11.1468", "longitude"=>"104.541"}, "144"=>{"code"=>"996", "name"=>"Boeng Thum Khang Lech", "latitude"=>"10.5532", "longitude"=>"104.503998"}, "145"=>{"code"=>"911", "name"=>"Boeng Tranh", "latitude"=>"11.0927", "longitude"=>"104.746002"}, "146"=>{"code"=>"1423", "name"=>"Boeng Veaeng", "latitude"=>"10.705", "longitude"=>"103.820999"}, "147"=>{"code"=>"423", "name"=>"Boh", "latitude"=>"13.7877", "longitude"=>"105.272003"}, "148"=>{"code"=>"671", "name"=>"Bon", "latitude"=>"10.8933", "longitude"=>"106.057999"}, "149"=>{"code"=>"1126", "name"=>"Bonna", "latitude"=>"11.416", "longitude"=>"104.869003"}, "150"=>{"code"=>"1708", "name"=>"Borei Kammeakkar", "latitude"=>"11.5103", "longitude"=>"104.762001"}, "151"=>{"code"=>"295", "name"=>"Bos", "latitude"=>"12.1636", "longitude"=>"106.078003"}, "152"=>{"code"=>"1335", "name"=>"Bos Khnaor", "latitude"=>"12.1779", "longitude"=>"105.325996"}, "153"=>{"code"=>"1490", "name"=>"Bos Laok", "latitude"=>"13.3871", "longitude"=>"102.934998"}, "154"=>{"code"=>"302", "name"=>"Bos Leav Kraom", "latitude"=>"12.4039", "longitude"=>"106.045998"}, "155"=>{"code"=>"1047", "name"=>"Bos Nhinh", "latitude"=>"10.6008", "longitude"=>"104.277"}, "156"=>{"code"=>"1525", "name"=>"Bos Pou", "latitude"=>"12.2962", "longitude"=>"105.413002"}, "157"=>{"code"=>"1592", "name"=>"Bos Roluoy", "latitude"=>"11.0246", "longitude"=>"105.385002"}, "158"=>{"code"=>"36", "name"=>"Bos Sbov", "latitude"=>"13.667", "longitude"=>"103.051003"}, "159"=>{"code"=>"729", "name"=>"Bos Svay", "latitude"=>"11.2343", "longitude"=>"105.885002"}, "160"=>{"code"=>"400", "name"=>"Bosbov", "latitude"=>"14.1333", "longitude"=>"103.489998"}, "161"=>{"code"=>"291", "name"=>"Botum Lech", "latitude"=>"12.933", "longitude"=>"104.679001"}, "162"=>{"code"=>"1143", "name"=>"Campuh Kaek", "latitude"=>"11.4799", "longitude"=>"104.958"}, "163"=>{"code"=>"812", "name"=>"Chaeng Maeng", "latitude"=>"11.2019", "longitude"=>"105.709999"}, "164"=>{"code"=>"132", "name"=>"Chak", "latitude"=>"11.7728", "longitude"=>"105.599998"}, "165"=>{"code"=>"363", "name"=>"Chak Cha", "latitude"=>"12.3708", "longitude"=>"106.728996"}, "166"=>{"code"=>"1594", "name"=>"Chakrei", "latitude"=>"13.3032", "longitude"=>"102.616997"}, "167"=>{"code"=>"1716", "name"=>"Chakto Tis", "latitude"=>"11.8208", "longitude"=>"104.768997"}, "168"=>{"code"=>"1264", "name"=>"Cham Srei", "latitude"=>"11.0897", "longitude"=>"103.905998"}, "169"=>{"code"=>"500", "name"=>"Chambak", "latitude"=>"11.1443", "longitude"=>"105.542999"}, "170"=>{"code"=>"676", "name"=>"Chambak Haer", "latitude"=>"13.6071", "longitude"=>"103.427002"}, "171"=>{"code"=>"816", "name"=>"Chambak Kaong", "latitude"=>"11.0893", "longitude"=>"105.709"}, "172"=>{"code"=>"323", "name"=>"Chambak Ti Muoy", "latitude"=>"12.272", "longitude"=>"105.813004"}, "173"=>{"code"=>"886", "name"=>"Chambak Tuem", "latitude"=>"10.6189", "longitude"=>"104.880997"}, "174"=>{"code"=>"1336", "name"=>"Chamkar Andoung", "latitude"=>"12.3379", "longitude"=>"105.181"}, "175"=>{"code"=>"565", "name"=>"Chamkar Chek Khang Cheung", "latitude"=>"12.5441", "longitude"=>"103.915001"}, "176"=>{"code"=>"1774", "name"=>"Chamkar Chrey Khang Cheung", "latitude"=>"12.2756", "longitude"=>"103.018997"}, "177"=>{"code"=>"1007", "name"=>"Chamkar Doung", "latitude"=>"11.2236", "longitude"=>"104.671997"}, "178"=>{"code"=>"359", "name"=>"Chamkar Kausu", "latitude"=>"10.7317", "longitude"=>"103.808998"}, "179"=>{"code"=>"540", "name"=>"Chamkar Kuoy Lech", "latitude"=>"11.4912", "longitude"=>"105.442001"}, "180"=>{"code"=>"1640", "name"=>"Chamkar Leu", "latitude"=>"13.5112", "longitude"=>"105.738998"}, "181"=>{"code"=>"1263", "name"=>"Chamkar Luong", "latitude"=>"11.0406", "longitude"=>"103.803001"}, "182"=>{"code"=>"63", "name"=>"Chamkar Ou", "latitude"=>"12.9262", "longitude"=>"103.143997"}, "183"=>{"code"=>"127", "name"=>"Chamkar Ruessei", "latitude"=>"13.0824", "longitude"=>"103.212997"}, "184"=>{"code"=>"142", "name"=>"Chamkar Samraong Pir", "latitude"=>"13.111", "longitude"=>"103.203003"}, "185"=>{"code"=>"495", "name"=>"Chamkar Srov", "latitude"=>"13.3508", "longitude"=>"102.352997"}, "186"=>{"code"=>"494", "name"=>"Chamkar Trab", "latitude"=>"13.37", "longitude"=>"102.358002"}, "187"=>{"code"=>"3", "name"=>"Chamnaom Kaeut", "latitude"=>"13.4413", "longitude"=>"102.941002"}, "188"=>{"code"=>"358", "name"=>"Chamnaot Ream", "latitude"=>"10.5981", "longitude"=>"103.627998"}, "189"=>{"code"=>"371", "name"=>"Chamraeun", "latitude"=>"13.0361", "longitude"=>"107.026001"}, "190"=>{"code"=>"1511", "name"=>"Chan Mul", "latitude"=>"11.737", "longitude"=>"106.245003"}, "191"=>{"code"=>"449", "name"=>"Chan Ra Ka", "latitude"=>"11.2513", "longitude"=>"105.514999"}, "192"=>{"code"=>"1662", "name"=>"Chan Teab", "latitude"=>"10.9945", "longitude"=>"104.600998"}, "193"=>{"code"=>"66", "name"=>"Changhour Svay", "latitude"=>"12.8692", "longitude"=>"103.108002"}, "194"=>{"code"=>"898", "name"=>"Changkaeub", "latitude"=>"11.0862", "longitude"=>"104.882004"}, "195"=>{"code"=>"992", "name"=>"Changriek", "latitude"=>"11.2414", "longitude"=>"104.546997"}, "196"=>{"code"=>"675", "name"=>"Chanlas Dai", "latitude"=>"13.6324", "longitude"=>"103.459999"}, "197"=>{"code"=>"1586", "name"=>"Chant Kruesna", "latitude"=>"11.3374", "longitude"=>"105.627998"}, "198"=>{"code"=>"653", "name"=>"Chantrea", "latitude"=>"10.8623", "longitude"=>"106.089996"}, "199"=>{"code"=>"740", "name"=>"Chantrei", "latitude"=>"11.2835", "longitude"=>"105.727997"}, "200"=>{"code"=>"74", "name"=>"Char", "latitude"=>"13.1645", "longitude"=>"103.039001"}, "201"=>{"code"=>"920", "name"=>"Char Ung Chan", "latitude"=>"13.7412", "longitude"=>"106.955002"}, "202"=>{"code"=>"1326", "name"=>"Chea Lea", "latitude"=>"11.9115", "longitude"=>"104.931999"}, "203"=>{"code"=>"311", "name"=>"Chea Montrei", "latitude"=>"12.8345", "longitude"=>"102.916"}, "204"=>{"code"=>"1627", "name"=>"Chea Sman", "latitude"=>"13.2929", "longitude"=>"104.002998"}, "205"=>{"code"=>"451", "name"=>"Cheach Khang Lech", "latitude"=>"11.6841", "longitude"=>"105.705002"}, "206"=>{"code"=>"1352", "name"=>"Cheach Thum", "latitude"=>"11.9089", "longitude"=>"105.865997"}, "207"=>{"code"=>"658", "name"=>"Chek", "latitude"=>"10.9286", "longitude"=>"106.130997"}, "208"=>{"code"=>"609", "name"=>"Chek Chau", "latitude"=>"12.5754", "longitude"=>"104.094002"}, "209"=>{"code"=>"975", "name"=>"Chen", "latitude"=>"10.7942", "longitude"=>"104.758003"}, "210"=>{"code"=>"4", "name"=>"Cheung Chab", "latitude"=>"13.4695", "longitude"=>"103.105003"}, "211"=>{"code"=>"1736", "name"=>"Cheung Chhnok", "latitude"=>"11.8784", "longitude"=>"104.940002"}, "212"=>{"code"=>"336", "name"=>"Cheung Khlu", "latitude"=>"12.0514", "longitude"=>"106.459"}, "213"=>{"code"=>"1735", "name"=>"Cheung Prey", "latitude"=>"12.0544", "longitude"=>"104.973"}, "214"=>{"code"=>"395", "name"=>"Cheung Tien", "latitude"=>"13.9186", "longitude"=>"103.553001"}, "215"=>{"code"=>"1429", "name"=>"Cheung Tuek", "latitude"=>"11.6903", "longitude"=>"105.563004"}, "216"=>{"code"=>"548", "name"=>"Cheung Tuek Ka", "latitude"=>"11.4982", "longitude"=>"105.330002"}, "217"=>{"code"=>"23", "name"=>"Cheung Voat", "latitude"=>"13.5934", "longitude"=>"103.183998"}, "218"=>{"code"=>"283", "name"=>"Chey Mongkol", "latitude"=>"12.594", "longitude"=>"105.018997"}, "219"=>{"code"=>"1753", "name"=>"Chey Nikom", "latitude"=>"11.8785", "longitude"=>"105.813004"}, "220"=>{"code"=>"412", "name"=>"Chey Nivot", "latitude"=>"14.2811", "longitude"=>"104.455002"}, "221"=>{"code"=>"420", "name"=>"Chhaeb Lech", "latitude"=>"13.7635", "longitude"=>"105.406998"}, "222"=>{"code"=>"1196", "name"=>"Chhak Chheu Neang", "latitude"=>"11.5231", "longitude"=>"104.737999"}, "223"=>{"code"=>"1318", "name"=>"Chhak Kandaol", "latitude"=>"12.0012", "longitude"=>"104.43"}, "224"=>{"code"=>"1570", "name"=>"Chhak Roka", "latitude"=>"12.5681", "longitude"=>"102.744003"}, "225"=>{"code"=>"506", "name"=>"Chhaoeng Chumnir", "latitude"=>"11.707", "longitude"=>"105.555"}, "226"=>{"code"=>"778", "name"=>"Chhay", "latitude"=>"10.7169", "longitude"=>"104.535004"}, "227"=>{"code"=>"1424", "name"=>"Chheu Kach", "latitude"=>"11.252", "longitude"=>"105.402"}, "228"=>{"code"=>"1124", "name"=>"Chheu Neang", "latitude"=>"11.404", "longitude"=>"104.846001"}, "229"=>{"code"=>"254", "name"=>"Chheu Teal", "latitude"=>"12.9415", "longitude"=>"104.570999"}, "230"=>{"code"=>"1646", "name"=>"Chheu Teal Bak", "latitude"=>"10.9152", "longitude"=>"104.835999"}, "231"=>{"code"=>"210", "name"=>"Chheu Teal Chrum", "latitude"=>"11.8441", "longitude"=>"105.727997"}, "232"=>{"code"=>"298", "name"=>"Chheu Teal Phluoh Kraom", "latitude"=>"12.2951", "longitude"=>"106.040001"}, "233"=>{"code"=>"1579", "name"=>"Chheu Traeng", "latitude"=>"11.3147", "longitude"=>"105.397003"}, "234"=>{"code"=>"538", "name"=>"Chhkae Koun", "latitude"=>"11.5824", "longitude"=>"105.474998"}, "235"=>{"code"=>"910", "name"=>"Chhlit Leu", "latitude"=>"10.6464", "longitude"=>"104.473"}, "236"=>{"code"=>"1513", "name"=>"Chhloung Muoy", "latitude"=>"11.9092", "longitude"=>"106.081001"}, "237"=>{"code"=>"1088", "name"=>"Chhmar Puon", "latitude"=>"11.3793", "longitude"=>"104.898003"}, "238"=>{"code"=>"557", "name"=>"Chhnal Moan", "latitude"=>"12.7123", "longitude"=>"103.217003"}, "239"=>{"code"=>"1268", "name"=>"Chhnok Tru", "latitude"=>"12.3662", "longitude"=>"104.449997"}, "240"=>{"code"=>"1386", "name"=>"Chhnuon", "latitude"=>"13.4257", "longitude"=>"105.217003"}, "241"=>{"code"=>"1493", "name"=>"Chhnuor", "latitude"=>"13.6328", "longitude"=>"103.110001"}, "242"=>{"code"=>"402", "name"=>"Chhuk", "latitude"=>"14.1935", "longitude"=>"103.518997"}, "243"=>{"code"=>"229", "name"=>"Chhuk Khsach", "latitude"=>"12.3954", "longitude"=>"105.114998"}, "244"=>{"code"=>"265", "name"=>"Chhuk Stueng", "latitude"=>"12.8691", "longitude"=>"105.132004"}, "245"=>{"code"=>"501", "name"=>"Chhvang", "latitude"=>"11.1089", "longitude"=>"105.599998"}, "246"=>{"code"=>"1209", "name"=>"Chhveang", "latitude"=>"11.6736", "longitude"=>"104.786003"}, "247"=>{"code"=>"1254", "name"=>"Chi Kha Lue", "latitude"=>"11.1701", "longitude"=>"103.679001"}, "248"=>{"code"=>"873", "name"=>"Chi Mreak", "latitude"=>"10.657", "longitude"=>"104.714996"}, "249"=>{"code"=>"310", "name"=>"Chi Pang", "latitude"=>"12.8126", "longitude"=>"102.894997"}, "250"=>{"code"=>"1754", "name"=>"Chi Peang", "latitude"=>"11.7823", "longitude"=>"106.010002"}, "251"=>{"code"=>"1261", "name"=>"Chi Phat", "latitude"=>"11.3274", "longitude"=>"103.529999"}, "252"=>{"code"=>"738", "name"=>"Chik Dei", "latitude"=>"11.5503", "longitude"=>"105.754997"}, "253"=>{"code"=>"1518", "name"=>"Chimoan Cheung", "latitude"=>"11.7707", "longitude"=>"105.945999"}, "254"=>{"code"=>"214", "name"=>"Chirou Kraom Ti Pir", "latitude"=>"12.0125", "longitude"=>"105.498001"}, "255"=>{"code"=>"268", "name"=>"Choam Boeng", "latitude"=>"12.8639", "longitude"=>"105.165001"}, "256"=>{"code"=>"426", "name"=>"Choam Khsant", "latitude"=>"14.2171", "longitude"=>"104.943001"}, "257"=>{"code"=>"122", "name"=>"Choam Triek", "latitude"=>"11.8124", "longitude"=>"106.206001"}, "258"=>{"code"=>"817", "name"=>"Choar Dom", "latitude"=>"10.7967", "longitude"=>"104.518997"}, "259"=>{"code"=>"20", "name"=>"Chob", "latitude"=>"13.6224", "longitude"=>"103.186996"}, "260"=>{"code"=>"769", "name"=>"Chob Kraom", "latitude"=>"13.5371", "longitude"=>"104.25"}, "261"=>{"code"=>"1533", "name"=>"Chob Krau", "latitude"=>"11.9156", "longitude"=>"105.609001"}, "262"=>{"code"=>"1449", "name"=>"Chob Leu", "latitude"=>"13.5461", "longitude"=>"104.247002"}, "263"=>{"code"=>"505", "name"=>"Chong Ampil", "latitude"=>"11.6615", "longitude"=>"105.429001"}, "264"=>{"code"=>"1418", "name"=>"Chong Kal", "latitude"=>"13.9501", "longitude"=>"103.577003"}, "265"=>{"code"=>"1700", "name"=>"Chong Kaoh", "latitude"=>"11.048", "longitude"=>"105.078003"}, "266"=>{"code"=>"271", "name"=>"Chong Pralay", "latitude"=>"12.8018", "longitude"=>"103.463997"}, "267"=>{"code"=>"1742", "name"=>"Chong Thnal Khang Lech", "latitude"=>"11.5601", "longitude"=>"104.878998"}, "268"=>{"code"=>"1673", "name"=>"Chongruk", "latitude"=>"11.2954", "longitude"=>"104.703003"}, "269"=>{"code"=>"533", "name"=>"Chouk Chey", "latitude"=>"11.3774", "longitude"=>"105.335999"}, "270"=>{"code"=>"1422", "name"=>"Chour Ti Muoy", "latitude"=>"11.5723", "longitude"=>"105.666"}, "271"=>{"code"=>"1576", "name"=>"Chour Ti Pir", "latitude"=>"11.5773", "longitude"=>"105.668999"}, "272"=>{"code"=>"673", "name"=>"Chrab", "latitude"=>"10.7007", "longitude"=>"104.653"}, "273"=>{"code"=>"1005", "name"=>"Chrab Tboun", "latitude"=>"11.402", "longitude"=>"104.755997"}, "274"=>{"code"=>"312", "name"=>"Chrab Veal", "latitude"=>"13.0828", "longitude"=>"103.228996"}, "275"=>{"code"=>"216", "name"=>"Chrak Chambak", "latitude"=>"11.9166", "longitude"=>"105.593002"}, "276"=>{"code"=>"1311", "name"=>"Chrak Tnaot", "latitude"=>"11.7463", "longitude"=>"104.485001"}, "277"=>{"code"=>"322", "name"=>"Chranaol", "latitude"=>"12.4993", "longitude"=>"106.236"}, "278"=>{"code"=>"765", "name"=>"Chranieng", "latitude"=>"13.8882", "longitude"=>"103.559998"}, "279"=>{"code"=>"906", "name"=>"Chranieng Khpos", "latitude"=>"11.1779", "longitude"=>"104.875"}, "280"=>{"code"=>"709", "name"=>"Chreav", "latitude"=>"13.3245", "longitude"=>"103.882004"}, "281"=>{"code"=>"879", "name"=>"Chres", "latitude"=>"10.9014", "longitude"=>"104.472"}, "282"=>{"code"=>"458", "name"=>"Chres Kaeut", "latitude"=>"11.6101", "longitude"=>"105.542999"}, "283"=>{"code"=>"462", "name"=>"Chrey", "latitude"=>"11.0613", "longitude"=>"105.595001"}, "284"=>{"code"=>"1301", "name"=>"Chrey Bak", "latitude"=>"12.1919", "longitude"=>"104.666"}, "285"=>{"code"=>"240", "name"=>"Chrey Cheung", "latitude"=>"12.7788", "longitude"=>"103.476997"}, "286"=>{"code"=>"717", "name"=>"Chrey Khang Cheung", "latitude"=>"13.2317", "longitude"=>"104.154999"}, "287"=>{"code"=>"869", "name"=>"Chrey Kouk Pou", "latitude"=>"10.8837", "longitude"=>"104.908997"}, "288"=>{"code"=>"1210", "name"=>"Chrey Loas", "latitude"=>"11.7169", "longitude"=>"104.788002"}, "289"=>{"code"=>"539", "name"=>"Chrey Phsar", "latitude"=>"11.5592", "longitude"=>"105.530998"}, "290"=>{"code"=>"1539", "name"=>"Chrey Pir", "latitude"=>"12.7776", "longitude"=>"103.476997"}, "291"=>{"code"=>"527", "name"=>"Chrey Thmei", "latitude"=>"10.9558", "longitude"=>"105.194"}, "292"=>{"code"=>"1763", "name"=>"Chrey Thum", "latitude"=>"11.0347", "longitude"=>"106.013"}, "293"=>{"code"=>"378", "name"=>"Chrey Yang", "latitude"=>"12.6638", "longitude"=>"107.237"}, "294"=>{"code"=>"1699", "name"=>"Chrouy Dang", "latitude"=>"11.4148", "longitude"=>"105.217003"}, "295"=>{"code"=>"90", "name"=>"Chrouy Krabau Ti Pir", "latitude"=>"11.8608", "longitude"=>"105.124001"}, "296"=>{"code"=>"1192", "name"=>"Chrouy Metrei Leu", "latitude"=>"11.778", "longitude"=>"105.014999"}, "297"=>{"code"=>"1444", "name"=>"Chrouy Neang Nguon", "latitude"=>"13.8293", "longitude"=>"103.517998"}, "298"=>{"code"=>"99", "name"=>"Chrouy Sdau", "latitude"=>"13.3298", "longitude"=>"103.059998"}, "299"=>{"code"=>"1255", "name"=>"Chrouy Svay Khang Kaeut", "latitude"=>"11.0285", "longitude"=>"103.677002"}, "300"=>{"code"=>"1357", "name"=>"Chrouy Thma", "latitude"=>"11.9952", "longitude"=>"105.471001"}, "301"=>{"code"=>"294", "name"=>"Chrouy Thma Kraom", "latitude"=>"12.2558", "longitude"=>"105.968002"}, "302"=>{"code"=>"1790", "name"=>"Chrouy Thma Leu", "latitude"=>"12.2511", "longitude"=>"105.976997"}, "303"=>{"code"=>"749", "name"=>"Chrung Sralau", "latitude"=>"10.6055", "longitude"=>"104.558998"}, "304"=>{"code"=>"1010", "name"=>"Chum Kriel", "latitude"=>"10.6063", "longitude"=>"104.209"}, "305"=>{"code"=>"1259", "name"=>"Chumnoab", "latitude"=>"11.6626", "longitude"=>"103.584"}, "306"=>{"code"=>"512", "name"=>"Chumpu Voan", "latitude"=>"11.741", "longitude"=>"105.533997"}, "307"=>{"code"=>"904", "name"=>"Chumrum", "latitude"=>"11.1402", "longitude"=>"104.873001"}, "308"=>{"code"=>"105", "name"=>"Chuor Kandal", "latitude"=>"12.1415", "longitude"=>"105.549004"}, "309"=>{"code"=>"968", "name"=>"Chuos", "latitude"=>"10.8092", "longitude"=>"104.808998"}, "310"=>{"code"=>"320", "name"=>"Chur Krouch", "latitude"=>"12.4277", "longitude"=>"106.151001"}, "311"=>{"code"=>"1033", "name"=>"Chvek", "latitude"=>"11.5786", "longitude"=>"104.598"}, "312"=>{"code"=>"959", "name"=>"Daeum Char", "latitude"=>"10.5511", "longitude"=>"104.445999"}, "313"=>{"code"=>"1270", "name"=>"Daeum Chreae", "latitude"=>"12.4139", "longitude"=>"104.473999"}, "314"=>{"code"=>"1622", "name"=>"Daeum Doung", "latitude"=>"10.7085", "longitude"=>"104.669998"}, "315"=>{"code"=>"1236", "name"=>"Daeum Kor", "latitude"=>"11.4862", "longitude"=>"104.945999"}, "316"=>{"code"=>"1109", "name"=>"Daeum Makkloea", "latitude"=>"11.5256", "longitude"=>"104.940002"}, "317"=>{"code"=>"1476", "name"=>"Daeum Mien", "latitude"=>"11.4828", "longitude"=>"104.950996"}, "318"=>{"code"=>"1480", "name"=>"Daeum Popel", "latitude"=>"11.9384", "longitude"=>"104.718002"}, "319"=>{"code"=>"102", "name"=>"Daeum Sdau", "latitude"=>"11.8841", "longitude"=>"105.438004"}, "320"=>{"code"=>"1110", "name"=>"Daeum Slaeng", "latitude"=>"11.5079", "longitude"=>"104.946999"}, "321"=>{"code"=>"381", "name"=>"Daeum Sral", "latitude"=>"12.4526", "longitude"=>"107.181999"}, "322"=>{"code"=>"1628", "name"=>"Dak Pou", "latitude"=>"13.358", "longitude"=>"103.876999"}, "323"=>{"code"=>"1631", "name"=>"Dam Daek Phsar", "latitude"=>"13.2429", "longitude"=>"104.125"}, "324"=>{"code"=>"143", "name"=>"Dam Spey", "latitude"=>"13.114", "longitude"=>"103.216003"}, "325"=>{"code"=>"1353", "name"=>"Dambae", "latitude"=>"12.0137", "longitude"=>"105.888"}, "326"=>{"code"=>"1365", "name"=>"Dambang Daek", "latitude"=>"11.9456", "longitude"=>"105.404999"}, "327"=>{"code"=>"1797", "name"=>"Damnak", "latitude"=>"13.8123", "longitude"=>"104.976997"}, "328"=>{"code"=>"601", "name"=>"Damnak Chambak", "latitude"=>"10.5557", "longitude"=>"104.285004"}, "329"=>{"code"=>"619", "name"=>"Damnak Chang'aeur", "latitude"=>"10.5417", "longitude"=>"104.310997"}, "330"=>{"code"=>"435", "name"=>"Damnak Chen", "latitude"=>"13.3774", "longitude"=>"105.124001"}, "331"=>{"code"=>"937", "name"=>"Damnak Kantuot", "latitude"=>"10.5741", "longitude"=>"104.463997"}, "332"=>{"code"=>"995", "name"=>"Damnak Kralanh Khang Kaeut", "latitude"=>"10.546", "longitude"=>"104.533997"}, "333"=>{"code"=>"1054", "name"=>"Damnak Luong", "latitude"=>"10.6949", "longitude"=>"104.267998"}, "334"=>{"code"=>"1280", "name"=>"Damnak Popul", "latitude"=>"12.241", "longitude"=>"104.675003"}, "335"=>{"code"=>"97", "name"=>"Damnak Pring Kaeut", "latitude"=>"11.841", "longitude"=>"105.426003"}, "336"=>{"code"=>"1679", "name"=>"Damnak Smach", "latitude"=>"11.7717", "longitude"=>"104.658997"}, "337"=>{"code"=>"1036", "name"=>"Damnak Trach", "latitude"=>"11.2922", "longitude"=>"104.321999"}, "338"=>{"code"=>"330", "name"=>"Damrae", "latitude"=>"12.8317", "longitude"=>"105.972"}, "339"=>{"code"=>"932", "name"=>"Damrei Leng", "latitude"=>"10.7132", "longitude"=>"104.504997"}, "340"=>{"code"=>"133", "name"=>"Damrel Ti Bei", "latitude"=>"11.8191", "longitude"=>"105.626999"}, "341"=>{"code"=>"564", "name"=>"Dang Rung", "latitude"=>"12.5635", "longitude"=>"103.892998"}, "342"=>{"code"=>"607", "name"=>"Dangkieb Kdam", "latitude"=>"12.2921", "longitude"=>"104.181999"}, "343"=>{"code"=>"382", "name"=>"Daoh Kramom", "latitude"=>"12.4623", "longitude"=>"107.182999"}, "344"=>{"code"=>"1283", "name"=>"Dar", "latitude"=>"12.3488", "longitude"=>"104.804001"}, "345"=>{"code"=>"116", "name"=>"Dar Kandal", "latitude"=>"11.7876", "longitude"=>"106.100998"}, "346"=>{"code"=>"1512", "name"=>"Dar Phsar", "latitude"=>"11.7845", "longitude"=>"106.088997"}, "347"=>{"code"=>"1136", "name"=>"Dei Edth Kaoh Phos", "latitude"=>"11.4959", "longitude"=>"105.084999"}, "348"=>{"code"=>"699", "name"=>"Dei Kraham", "latitude"=>"13.207", "longitude"=>"103.976997"}, "349"=>{"code"=>"1647", "name"=>"Dei Lou", "latitude"=>"13.4847", "longitude"=>"106.986"}, "350"=>{"code"=>"1032", "name"=>"Doek Peang", "latitude"=>"11.6447", "longitude"=>"104.667999"}, "351"=>{"code"=>"1688", "name"=>"Dom Khvet", "latitude"=>"11.7355", "longitude"=>"104.593002"}, "352"=>{"code"=>"555", "name"=>"Doun Ba", "latitude"=>"12.7614", "longitude"=>"103.247002"}, "353"=>{"code"=>"186", "name"=>"Doun Chhuk", "latitude"=>"12.9271", "longitude"=>"104.785004"}, "354"=>{"code"=>"1740", "name"=>"Doun Dom", "latitude"=>"12.0154", "longitude"=>"105.072998"}, "355"=>{"code"=>"452", "name"=>"Doun Koeng", "latitude"=>"11.5683", "longitude"=>"105.585999"}, "356"=>{"code"=>"9", "name"=>"Doun Loek", "latitude"=>"13.4488", "longitude"=>"103.228996"}, "357"=>{"code"=>"702", "name"=>"Doun Num", "latitude"=>"13.3091", "longitude"=>"104.000999"}, "358"=>{"code"=>"1737", "name"=>"Doun Paen", "latitude"=>"12.0832", "longitude"=>"104.977997"}, "359"=>{"code"=>"642", "name"=>"Doun Reach", "latitude"=>"13.1336", "longitude"=>"104.318001"}, "360"=>{"code"=>"822", "name"=>"Doun Sar", "latitude"=>"11.2221", "longitude"=>"105.728996"}, "361"=>{"code"=>"625", "name"=>"Doun Sva", "latitude"=>"13.6799", "longitude"=>"103.638"}, "362"=>{"code"=>"205", "name"=>"Doun Teav", "latitude"=>"13.1509", "longitude"=>"103.214996"}, "363"=>{"code"=>"1744", "name"=>"Doun Thi", "latitude"=>"12.123", "longitude"=>"105.342003"}, "364"=>{"code"=>"208", "name"=>"Doun Tor", "latitude"=>"12.2223", "longitude"=>"105.460999"}, "365"=>{"code"=>"199", "name"=>"Doung", "latitude"=>"13.2557", "longitude"=>"102.776001"}, "366"=>{"code"=>"73", "name"=>"Hai San", "latitude"=>"13.1078", "longitude"=>"103.141998"}, "367"=>{"code"=>"296", "name"=>"Hanchey Ti Bei", "latitude"=>"12.2542", "longitude"=>"105.944"}, "368"=>{"code"=>"801", "name"=>"Hang Khou Suon", "latitude"=>"13.5523", "longitude"=>"105.977997"}, "369"=>{"code"=>"943", "name"=>"Hat Pak", "latitude"=>"13.8445", "longitude"=>"106.697998"}, "370"=>{"code"=>"694", "name"=>"K'aek Tum", "latitude"=>"13.5377", "longitude"=>"103.742996"}, "371"=>{"code"=>"1171", "name"=>"K'am Samnar Kraom", "latitude"=>"10.9213", "longitude"=>"105.183998"}, "372"=>{"code"=>"396", "name"=>"Ka", "latitude"=>"13.9478", "longitude"=>"103.575996"}, "373"=>{"code"=>"1731", "name"=>"Ka At", "latitude"=>"11.9346", "longitude"=>"104.717003"}, "374"=>{"code"=>"944", "name"=>"Ka Choun Kraom", "latitude"=>"13.9621", "longitude"=>"106.889999"}, "375"=>{"code"=>"858", "name"=>"Ka Laeng", "latitude"=>"13.501", "longitude"=>"107.058998"}, "376"=>{"code"=>"845", "name"=>"Ka Nat", "latitude"=>"13.9273", "longitude"=>"107.254997"}, "377"=>{"code"=>"929", "name"=>"Ka Tang", "latitude"=>"13.7748", "longitude"=>"107.419998"}, "378"=>{"code"=>"460", "name"=>"Ka Thum", "latitude"=>"10.9949", "longitude"=>"105.558998"}, "379"=>{"code"=>"917", "name"=>"Ka Tieng", "latitude"=>"13.6361", "longitude"=>"106.957001"}, "380"=>{"code"=>"770", "name"=>"Kab Dai", "latitude"=>"13.8364", "longitude"=>"103.785004"}, "381"=>{"code"=>"1522", "name"=>"Kab Kou Thmei", "latitude"=>"13.1047", "longitude"=>"103.195"}, "382"=>{"code"=>"243", "name"=>"Kab Thlok", "latitude"=>"12.8972", "longitude"=>"104.721001"}, "383"=>{"code"=>"1040", "name"=>"Kab Tuk", "latitude"=>"11.3807", "longitude"=>"104.332001"}, "384"=>{"code"=>"1561", "name"=>"Kach Roteh", "latitude"=>"12.9496", "longitude"=>"103.348999"}, "385"=>{"code"=>"618", "name"=>"Kaeb", "latitude"=>"10.4905", "longitude"=>"104.325996"}, "386"=>{"code"=>"1380", "name"=>"Kaeb Thmei", "latitude"=>"10.5742", "longitude"=>"104.153"}, "387"=>{"code"=>"287", "name"=>"Kaeng Prasat", "latitude"=>"12.7648", "longitude"=>"105.973"}, "388"=>{"code"=>"1588", "name"=>"Kaev Sna", "latitude"=>"11.3515", "longitude"=>"105.499001"}, "389"=>{"code"=>"595", "name"=>"Kaev Sovann Leu", "latitude"=>"12.5464", "longitude"=>"103.929001"}, "390"=>{"code"=>"848", "name"=>"Kak", "latitude"=>"13.7042", "longitude"=>"107.238998"}, "391"=>{"code"=>"272", "name"=>"Kakaoh", "latitude"=>"12.8436", "longitude"=>"103.400002"}, "392"=>{"code"=>"70", "name"=>"Kaksekam", "latitude"=>"13.2623", "longitude"=>"103.093002"}, "393"=>{"code"=>"923", "name"=>"Kalai Pir", "latitude"=>"13.8351", "longitude"=>"106.955002"}, "394"=>{"code"=>"856", "name"=>"Kam Bak", "latitude"=>"13.6774", "longitude"=>"106.848999"}, "395"=>{"code"=>"305", "name"=>"Kambaor", "latitude"=>"12.5377", "longitude"=>"106.067001"}, "396"=>{"code"=>"453", "name"=>"Kamchay Mear Cheung", "latitude"=>"11.6147", "longitude"=>"105.691002"}, "397"=>{"code"=>"1407", "name"=>"Kammeak Neath", "latitude"=>"12.5607", "longitude"=>"105.052002"}, "398"=>{"code"=>"881", "name"=>"Kamnab", "latitude"=>"11.0339", "longitude"=>"104.472"}, "399"=>{"code"=>"1330", "name"=>"Kampal", "latitude"=>"12.1196", "longitude"=>"104.975998"}, "400"=>{"code"=>"621", "name"=>"Kampeaeng", "latitude"=>"12.402", "longitude"=>"103.814003"}, "401"=>{"code"=>"775", "name"=>"Kamphun", "latitude"=>"13.5508", "longitude"=>"106.095001"}, "402"=>{"code"=>"117", "name"=>"Kampoan", "latitude"=>"11.9229", "longitude"=>"106.099998"}, "403"=>{"code"=>"1454", "name"=>"Kampong", "latitude"=>"10.6469", "longitude"=>"104.875"}, "404"=>{"code"=>"1466", "name"=>"Kampong Bay Khang Cheung", "latitude"=>"10.6116", "longitude"=>"104.181999"}, "405"=>{"code"=>"1071", "name"=>"Kampong Bay Khang Tboung", "latitude"=>"10.613", "longitude"=>"104.185997"}, "406"=>{"code"=>"1284", "name"=>"Kampong Boeng", "latitude"=>"12.2712", "longitude"=>"104.730003"}, "407"=>{"code"=>"979", "name"=>"Kampong Cham", "latitude"=>"13.9451", "longitude"=>"106.760002"}, "408"=>{"code"=>"98", "name"=>"Kampong Chamlang", "latitude"=>"11.924", "longitude"=>"105.322998"}, "409"=>{"code"=>"1369", "name"=>"Kampong Chanloh Lech", "latitude"=>"12.0937", "longitude"=>"105.552002"}, "410"=>{"code"=>"1547", "name"=>"Kampong Chheu Teal", "latitude"=>"12.8688", "longitude"=>"105.071999"}, "411"=>{"code"=>"1058", "name"=>"Kampong Kaes", "latitude"=>"10.5937", "longitude"=>"104.246002"}, "412"=>{"code"=>"1542", "name"=>"Kampong Kdei", "latitude"=>"12.9388", "longitude"=>"104.574997"}, "413"=>{"code"=>"640", "name"=>"Kampong Kdei Pir", "latitude"=>"13.1212", "longitude"=>"104.343002"}, "414"=>{"code"=>"1702", "name"=>"Kampong Kong", "latitude"=>"11.1392", "longitude"=>"105.080002"}, "415"=>{"code"=>"325", "name"=>"Kampong Kor", "latitude"=>"12.272", "longitude"=>"105.966003"}, "416"=>{"code"=>"244", "name"=>"Kampong Kou Leu", "latitude"=>"12.7089", "longitude"=>"104.794998"}, "417"=>{"code"=>"195", "name"=>"Kampong Krabei", "latitude"=>"13.0959", "longitude"=>"103.202003"}, "418"=>{"code"=>"1011", "name"=>"Kampong Kraeng", "latitude"=>"10.6368", "longitude"=>"104.178001"}, "419"=>{"code"=>"899", "name"=>"Kampong Leav", "latitude"=>"11.1587", "longitude"=>"105.023003"}, "420"=>{"code"=>"1446", "name"=>"Kampong Luong", "latitude"=>"10.9912", "longitude"=>"104.981003"}, "421"=>{"code"=>"483", "name"=>"Kampong Popil", "latitude"=>"11.6532", "longitude"=>"105.141998"}, "422"=>{"code"=>"759", "name"=>"Kampong Pou", "latitude"=>"10.9889", "longitude"=>"104.982002"}, "423"=>{"code"=>"374", "name"=>"Kampong Preah", "latitude"=>"13.0255", "longitude"=>"103.306"}, "424"=>{"code"=>"1384", "name"=>"Kampong Preah Ent", "latitude"=>"13.9747", "longitude"=>"105.848999"}, "425"=>{"code"=>"1228", "name"=>"Kampong Pring", "latitude"=>"11.4285", "longitude"=>"105.049004"}, "426"=>{"code"=>"419", "name"=>"Kampong Putrea", "latitude"=>"13.5136", "longitude"=>"105.195"}, "427"=>{"code"=>"94", "name"=>"Kampong Reab Kraom", "latitude"=>"11.9129", "longitude"=>"105.373001"}, "428"=>{"code"=>"596", "name"=>"Kampong Roka", "latitude"=>"12.6025", "longitude"=>"103.949997"}, "429"=>{"code"=>"202", "name"=>"Kampong Sambuor", "latitude"=>"13.1343", "longitude"=>"103.223999"}, "430"=>{"code"=>"1238", "name"=>"Kampong Samnanh", "latitude"=>"11.4671", "longitude"=>"104.948997"}, "431"=>{"code"=>"1521", "name"=>"Kampong Seima", "latitude"=>"13.0537", "longitude"=>"103.198997"}, "432"=>{"code"=>"450", "name"=>"Kampong Snae", "latitude"=>"11.3744", "longitude"=>"105.398003"}, "433"=>{"code"=>"1383", "name"=>"Kampong Sralau", "latitude"=>"14.0807", "longitude"=>"105.787003"}, "434"=>{"code"=>"a1", "name"=>"Kampong Leav1", "latitude"=>"11.1587", "longitude"=>"105.023003"}, "435"=>{"code"=>"a2", "name"=>"Kampong Luong2", "latitude"=>"10.9912", "longitude"=>"104.981003"}, "436"=>{"code"=>"a3", "name"=>"Kampong Popil3", "latitude"=>"11.6532", "longitude"=>"105.141998"}, "437"=>{"code"=>"a4", "name"=>"Kampong Pou4", "latitude"=>"10.9889", "longitude"=>"104.982002"}, "438"=>{"code"=>"a5", "name"=>"Kampong Preah5", "latitude"=>"13.0255", "longitude"=>"103.306"}}
-
1
field_location = {"name"=>"location", "code"=>"location", "kind"=>"location", "ord"=>"1", "layer_id"=>"56", "is_enable_field_logic"=>"false", "config"=>{locations: config_locations}}
-
1
layer = {"name"=>"layer1", "ord"=>"1", "fields_attributes"=>{"0"=>field_location}}
-
-
1
post :create, {layer: layer, collection_id: collection.id}
-
-
1
expect(response).to be_success
-
1
json = JSON.parse response.body
-
1
expect(json["name"]).to eq("layer1")
-
1
expect(json["fields"][0]["name"]).to eq("location")
-
1
expect(json["fields"][0]["code"]).to eq("location")
-
1
expect(json["fields"][0]["kind"]).to eq("location")
-
1
expect(json["fields"][0]["config"]["locations"].size).to eq(439)
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe MembershipsController do
-
1
include Devise::TestHelpers
-
-
6
let!(:user) { User.make email: 'foo@test.com' }
-
6
let!(:user_2) { User.make email: 'bar@test.com' }
-
6
let!(:collection) { user.create_collection(Collection.make_unsaved) }
-
-
6
before(:each) { sign_in user }
-
-
1
describe "search" do
-
1
it "should find users that have membership" do
-
1
get :search, collection_id: collection.id, term: 'bar'
-
1
expect(JSON.parse(response.body).count).to eq(0)
-
end
-
-
1
it "should find user" do
-
1
get :search, collection_id: collection.id, term: 'foo'
-
1
json = JSON.parse response.body
-
-
1
expect(json.size).to eq(1)
-
1
expect(json[0]).to eq('foo@test.com')
-
end
-
-
1
context "without term" do
-
1
it "should return all users in the collection" do
-
1
get :search, collection_id: collection.id
-
1
expect(JSON.parse(response.body).count).to eq(1)
-
end
-
end
-
end
-
-
1
describe "create" do
-
1
it "should create with owner false" do
-
1
user_2.memberships.create! :collection_id => collection.id
-
1
expect(user_2.memberships[0]).not_to be_owner
-
end
-
-
1
it "should create with owner true" do
-
1
collection1 = user.create_collection(Collection.make_unsaved)
-
1
expect(collection1.memberships.first).to be_owner
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe NuntiumController do
-
1
describe "POST 'receive'" do
-
1
before(:each) do
-
7
@collection = Collection.make(:name => 'Healt Center')
-
7
@layer = @collection.layers.make(:name => "default")
-
7
@user = User.make(:phone_number => '85512345678')
-
7
f1 = @layer.numeric_fields.make(:id => 10, :name => "Ambulance", :code => "AB", :ord => 1)
-
7
f2 = @layer.numeric_fields.make(:id => 11, :name => "Doctor", :code => "DO", :ord => 2)
-
7
@collection.layer_memberships.create(:user => @user, :layer_id => @layer.id, :read => true, :write => true)
-
7
@collection.memberships.create(:user => @user, :admin => false)
-
7
site = @collection.sites.make(:name => "SiemReap Health Center", :lat => 9, :lng => 9, :id_with_prefix => "AA1", :properties => {"10"=>5, "11"=>2})
-
7
@params = { :guid => "123", :from => "sms://85512345678", :body => "dyrm u AA1 AB=2" }
-
7
@message = Message.create(@params)
-
end
-
-
1
it "should save message" do
-
1
expect(Message).to receive(:create!).with(:guid => "123", :from => "sms://85512345678", :body => "dyrm u AA1 AB=2").and_return(@message)
-
1
post :receive, @params
-
end
-
-
1
describe "should validate post data" do
-
1
def post_receive_without(param)
-
12
post :receive, @params.clone.delete_if { |k, v| k == param }
-
end
-
-
1
it "should response error" do
-
1
post :receive
-
1
expect(response.response_code).to eq(400)
-
end
-
-
1
it "should check for guid" do
-
1
post_receive_without :guid
-
1
expect(response.body).to match /Validation failed: Guid can't be blank/
-
end
-
-
1
it "should check for from" do
-
1
post_receive_without :from
-
1
expect(response.body).to match /Validation failed: From can't be blank/
-
end
-
-
1
it "should check for body" do
-
1
post_receive_without :body
-
1
expect(response.body).to match /Validation failed: Body can't be blank/
-
end
-
end
-
1
describe "message processing" do
-
1
before(:each) do
-
2
@message = Message.create @params
-
2
expect(controller).to receive(:save_message).and_return(@message)
-
end
-
-
1
it "should process message" do
-
1
post :receive, @params
-
1
expect(response.response_code).to eq(200)
-
end
-
-
1
it "should response plain text" do
-
1
post :receive, @params
-
1
expect(response.content_type).to eq("text/plain")
-
end
-
end
-
end
-
-
1
describe "authenticate" do
-
1
it "should authenticate via http basic authentication" do
-
1
post :authenticate
-
1
expect(response.response_code).to eq(401)
-
end
-
-
1
it "should response unauthorized for bad user" do
-
1
request.env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("foo", "secret")
-
1
post :authenticate
-
1
expect(response.response_code).to eq(401)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe QuotasController, :type => :controller do
-
1
include Devise::TestHelpers
-
1
render_views
-
-
3
let(:user) { User.make }
-
3
let(:collection) { Collection.make }
-
-
3
before(:each) { sign_in user }
-
1
it 'should upate message quota on collection from 0 to 10' do
-
1
expect{
-
1
post :create, collection_id: collection.id, quota: 10, format: 'json'
-
}.to change{
-
2
c = Collection.find collection.id
-
2
c.quota
-
}.from(0).to(10)
-
end
-
-
1
it 'should respond the collection depend on collection_id' do
-
1
get :show, id: collection.id
-
1
assert_response :success
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe SitesController do
-
1
include Devise::TestHelpers
-
-
14
let!(:user) { User.make }
-
14
let!(:collection) { user.create_collection(Collection.make_unsaved) }
-
14
let!(:layer) { collection.layers.make }
-
-
14
let!(:site) { collection.sites.make id: 1234}
-
-
14
let!(:text) { layer.text_fields.make code: 'text'}
-
4
let(:numeric) { layer.numeric_fields.make code: 'n' }
-
14
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'next_id' => 3, 'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
14
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'next_id' => 3, 'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
1
config_hierarchy = [{ id: '60', name: 'Dad', sub: [{id: '100', name: 'Son'}, {id: '101', name: 'Bro'}]}]
-
14
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
14
let!(:site_field) { layer.site_fields.make :code => 'site' }
-
14
let!(:date) { layer.date_fields.make :code => 'date' }
-
14
let!(:director) { layer.user_fields.make :code => 'user' }
-
14
let!(:email_field) { layer.email_fields.make :code => 'email' }
-
-
14
before(:each) { sign_in user }
-
-
#TODO: Move this functionality to api and rescue validation-exceptions with response_code = 400 and a 'check api doc' message
-
-
1
it 'should validate format for numeric field' do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: numeric.es_code, value: 'not a number'
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid numeric value in field #{numeric.code}")
-
1
post :update_property, site_id: site.id, format: 'json', es_code: numeric.es_code, value: '2'
-
1
validate_site_property_value(site, numeric, 2)
-
end
-
-
1
it "should validate format for date field in mm/dd/yyyy format" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: date.es_code, value: '11/27/2012'
-
1
validate_site_property_value(site, date, "2012-11-27T00:00:00Z")
-
1
post :update_property, site_id: site.id, format: 'json', es_code: date.es_code, value: "117"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid date value in field #{date.code}")
-
end
-
-
1
it "should validate format for hierarchy field" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: hierarchy.es_code, value: "101"
-
1
validate_site_property_value(site, hierarchy, "101")
-
1
post :update_property, site_id: site.id, format: 'json', es_code: hierarchy.es_code, value: "Dad"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid hierarchy option in field #{hierarchy.code}")
-
end
-
-
1
it "should validate format for select_one field" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_one.es_code, value: "1"
-
1
validate_site_property_value(site, select_one, 1)
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_one.es_code, value: "one"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid option in field #{select_one.code}")
-
end
-
-
1
it "should validate format for select_many field" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_many.es_code, value: ["1"]
-
1
validate_site_property_value(site, select_many, [1])
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_many.es_code, value: ["2", "1"]
-
1
validate_site_property_value(site, select_many, [2, 1])
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_many.es_code, value: "2, 1"
-
1
validate_site_property_value(site, select_many, [2, 1])
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_many.es_code, value: "[two,]"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid option '[two' in field #{select_many.code}")
-
1
post :update_property, site_id: site.id, format: 'json', es_code: select_many.es_code, value: "two,one"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid option 'two' in field #{select_many.code}")
-
end
-
-
1
it "should validate format for site field" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: site_field.es_code, value: "1234"
-
1
validate_site_property_value(site, site_field, "1234")
-
1
post :update_property, site_id: site.id, format: 'json', es_code: site_field.es_code, value: 23
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Non-existent site-id in field #{site_field.code}")
-
end
-
-
1
it "should validate format for user field" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: director.es_code, value: user.email
-
1
validate_site_property_value(site, director, user.email)
-
1
post :update_property, site_id: site.id, format: 'json', es_code: director.es_code, value: "inexisting@email.com"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Non-existent user email address in field #{director.code}")
-
end
-
-
1
it "should validate format for email field" do
-
1
post :update_property, site_id: site.id, format: 'json', es_code: email_field.es_code, value: "valid@email.com"
-
1
validate_site_property_value(site, email_field, "valid@email.com")
-
1
post :update_property, site_id: site.id, format: 'json', es_code: email_field.es_code, value: "v3@@e.mail.c.om"
-
1
json = JSON.parse response.body
-
1
expect(json["error_message"]).to eq("Invalid email address in field #{email_field.code}")
-
end
-
-
1
it 'should create a new site' do
-
1
site_params = {:name => "new site", :lat => "-7.338135", :lng => "29.836455", :properties => {
-
text.es_code => "new text",
-
numeric.es_code => "123",
-
select_one.es_code => 1,
-
select_many.es_code => [1,2],
-
hierarchy.es_code => "101",
-
site_field.es_code=> site.id,
-
date.es_code => "2013-02-05T00:00:00Z",
-
director.es_code => user.email,
-
email_field.es_code => "myemail@mail.com" }}.to_json
-
1
post :create, {:collection_id => collection.id, :site => site_params}
-
-
1
expect(response).to be_success
-
1
new_site = Site.find_by_name "new site"
-
-
-
1
validate_site_property_value(new_site, text, "new text")
-
1
validate_site_property_value(new_site, numeric, 123)
-
1
validate_site_property_value(new_site, select_one, 1)
-
1
validate_site_property_value(new_site, select_many, [1,2])
-
1
validate_site_property_value(new_site, hierarchy, "101")
-
1
validate_site_property_value(new_site, site_field, site.id)
-
1
validate_site_property_value(new_site, date, "2013-02-05T00:00:00Z")
-
1
validate_site_property_value(new_site, director, user.email)
-
1
validate_site_property_value(new_site, email_field, "myemail@mail.com")
-
end
-
-
1
describe 'updating site' do
-
-
1
it 'should update only name' do
-
1
site_params = {:name => "new site"}.to_json
-
1
site.update_attributes properties: { numeric.es_code => 123 }
-
1
post :update, {:collection_id => collection.id, :id => site.id, :site => site_params }
-
-
1
expect(response).to be_success
-
1
new_site = Site.find_by_name "new site"
-
1
expect(new_site.properties).to eq site.properties
-
end
-
-
1
it 'should update a single property' do
-
1
site_params = {:properties => { text.es_code => "new text" }}.to_json
-
1
post :update, {:collection_id => collection.id, :id => site.id, :site => site_params }
-
-
1
expect(response).to be_success
-
1
new_site = Site.find_by_name site.name
-
1
new_site.properties[text.es_code.to_s]
-
end
-
end
-
-
1
it "can destroy site" do
-
1
delete :destroy, id: site.id, collection_id: collection.id
-
-
1
expect(Site.find_by_id(site.id)).to be_nil
-
end
-
-
1
def validate_site_property_value(site, property, value)
-
19
site.reload
-
19
expect(site.properties["#{property.es_code}"]).to eq(value)
-
end
-
-
1
describe 'analytic' do
-
1
it 'should changed user.site_count by 1' do
-
1
expect {
-
1
post :create, site: "{\"name\":\"site_01\",\"lat\":8.932599568335238,\"lng\":99.27246091406255,\"properties\":{}}", collection_id: collection.id
-
}.to change{
-
2
u = User.find user
-
2
u.site_count
-
}.from(0).to(1)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe SitesPermissionController do
-
1
include Devise::TestHelpers
-
-
6
let!(:user) { User.make }
-
6
let!(:user2) { User.make }
-
6
let!(:collection) { user.create_collection(Collection.make_unsaved) }
-
5
let(:membership2) { collection.memberships.create! :user_id => user2.id, :admin => false }
-
6
before(:each) { sign_in user }
-
-
1
describe 'POST create' do
-
1
it 'should response ok' do
-
1
post :create, "sites_permission" => {"user_id" => user.id}, "collection_id" => collection.id
-
1
expect(response.body).to eq("\"ok\"")
-
end
-
end
-
-
1
describe 'GET index' do
-
5
let!(:membership) { collection.memberships[0] }
-
5
let!(:read_sites_permission) { membership.create_read_sites_permission all_sites: true }
-
5
let!(:read_all_sites_permission) { membership.create_read_sites_permission all_sites: true, some_sites: [] }
-
5
let!(:write_sites_permission) { membership2.create_write_sites_permission all_sites: false, some_sites: [{id: 1, name: 'Bayon clinic'}] }
-
5
let!(:write_all_sites_permission) { membership.create_write_sites_permission all_sites: true, some_sites: [] }
-
-
1
it "should response include read sites permission" do
-
1
get :index, collection_id: collection.id
-
1
expect(response.body).to include "\"read\":#{read_sites_permission.to_json}"
-
end
-
-
1
it "should response include write sites permission" do
-
1
get :index, collection_id: collection.id
-
1
expect(response.body).to include "\"write\":#{write_all_sites_permission.to_json}"
-
end
-
-
1
it "should return all sites true for all actions if user is admin" do
-
1
get :index, collection_id: collection.id
-
1
expect(response.body).to include "\"write\":#{write_all_sites_permission.to_json}"
-
1
expect(response.body).to include "\"write\":#{read_all_sites_permission.to_json}"
-
end
-
-
1
context "when user is not a member of collection" do
-
2
let(:collection_2) { Collection.make }
-
-
1
it "should response no permission" do
-
1
get :index, collection_id: collection_2.id
-
1
expect(response.body).to eq(SitesPermission.no_permission.to_json)
-
end
-
end
-
end
-
end
-
# encoding: UTF-8
-
-
1
require 'spec_helper'
-
-
1
describe CSV do
-
1
it "Open CSV encoded in utf-8" do
-
1
with_tmp_file('utf8.csv') do |tmp_file|
-
1
CSV.open(tmp_file, "wb", encoding: "utf-8") do |csv|
-
1
csv << ["é", "ñ", "ç", "ø"]
-
end
-
-
1
expect(CSV.read(tmp_file)).to eq([["é", "ñ", "ç", "ø"]])
-
end
-
end
-
-
1
it "Open CSV encoded in latin1" do
-
1
with_tmp_file('latin1.csv') do |tmp_file|
-
1
CSV.open(tmp_file, "wb", encoding: "ISO-8859-1") do |csv|
-
1
csv << ["é", "ñ", "ç", "ø"]
-
end
-
-
1
expect(CSV.read(tmp_file)).to eq([["é", "ñ", "ç", "ø"]])
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Epsg do
-
3
let(:content) { 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]' }
-
-
1
describe 'esri projection' do
-
1
it 'should get wgs84' do
-
1
expect(Epsg.wgs84).to eq(content)
-
end
-
-
1
it 'should get epsg:4326' do
-
1
expect(Epsg['4326']).to eq(content)
-
end
-
-
1
it 'should get other code' do
-
1
expect(Epsg['5726']).not_to be_nil
-
end
-
-
1
context 'non-existed code' do
-
1
it 'should return nil' do
-
1
expect(Epsg['non-existed']).to be_nil
-
end
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe String do
-
2
let!(:template_string) { 'Dear [Site Name], your balance is now [money].' }
-
-
1
it "render a string from a template string" do
-
1
expect(template_string.render_template_string({'Site Name' => 'Dane', 'money' => '10$'})).to eq('Dear Dane, your balance is now 10$.')
-
end
-
-
end
-
-
1
require 'spec_helper'
-
-
1
describe "Accounts" do
-
-
1
it "should create an account", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
login_as (@user)
-
visit collections_path
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "cancel_account" do
-
-
1
it " should cancel account", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
# find(:xpath, '//div[@id="User"]').click
-
# click_link 'Settings'
-
find(:xpath, '//div[@id="toolbar"]/ul[2]/li[2]/a').click
-
click_link 'Cancel my account'
-
page.driver.browser.switch_to.alert.accept
-
sleep 2
-
page.save_screenshot 'Cancel_account.png'
-
expect(page).to have_content 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "change_password_fail" do
-
-
1
it " should not change password", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
# find(:xpath, '//div[@id="User"]').click
-
# click_link 'Settings'
-
find(:xpath, '//div[@id="toolbar"]/ul[2]/li[2]/a').click
-
within "form#edit_user" do
-
fill_in "user_current_password", :with => @user.password
-
fill_in "user_password", :with => 'dexmor.15'
-
end
-
click_button 'Update'
-
sleep 1
-
page.save_screenshot 'Change_password_fail.png'
-
expect(page).to have_content "Password doesn't match confirmation"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "change_password" do
-
-
1
it " should change password", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
# find(:xpath, '//div[@id="User"]').click
-
# click_link 'Settings'
-
find(:xpath, '//div[@id="toolbar"]/ul[2]/li[2]/a').click
-
within "form#edit_user" do
-
fill_in "user_current_password", :with => @user.password
-
fill_in "user_password", :with => 'dexmor.15'
-
fill_in "user_password_confirmation", :with => 'dexmor.15'
-
end
-
click_button 'Update'
-
sleep 1
-
page.save_screenshot 'Change_password.png'
-
expect(page).to have_content 'Account updated successfully'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "log_out" do
-
-
1
it "should log out", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
login_as (@user)
-
visit collections_path
-
find_by_id('User').click
-
click_link('Sign Out')
-
sleep 3
-
page.save_screenshot 'Log_out.png'
-
expect(page).to have_content 'Signed out successfully'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "login_fail" do
-
-
1
it "should fail to login", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
visit collections_path
-
within "form#new_user" do
-
fill_in "Email", :with => @user.email
-
fill_in "Password", :with => '12345098765'
-
click_button('Log In')
-
end
-
sleep 2
-
page.save_screenshot 'login_fail.png'
-
expect(page).to have_content("Invalid email or password.")
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "login" do
-
-
1
it "should login", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
visit collections_path
-
within "form#new_user" do
-
fill_in "Email", :with => @user.email
-
fill_in "Password", :with => @user.password
-
click_button('Log In')
-
end
-
page.save_screenshot 'login.png'
-
expect(page).to have_content("Signed in successfully")
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "navigate_carrousel" do
-
-
1
it "should navigate carrousel", js:true do
-
visit "/"
-
sleep 1
-
find(:xpath, '//div[@id="container"]/div/div[3]/div/div/div[3]/a').click
-
expect(page).to have_content 'Maintain'
-
find(:xpath, '//div[@id="container"]/div/div[3]/div/div/div[3]/a').click
-
expect(page).to have_content 'Open Source'
-
page.save_screenshot 'navigate_carrousel.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "reset_password" do
-
-
1
it "should reset password", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
visit collections_path
-
within "form#new_user" do
-
fill_in "Email", :with => @user.email
-
end
-
sleep 4
-
click_link 'Reset it'
-
sleep 2
-
fill_in "user_email", :with => @user.email
-
click_button "Send me reset password instructions"
-
sleep 2
-
page.save_screenshot 'reset_password.png'
-
expect(page).to have_content 'You will receive an email with instructions about how to reset your password in a few minutes.'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "show_more_info" do
-
-
1
it "should show user more info", js:true do
-
visit "/"
-
sleep 1
-
click_link "Find out how"
-
sleep 1
-
page.save_screenshot 'Show_more_info.png'
-
expect(page).to have_content "How does it work?"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "sign_up" do
-
-
1
it "should sign up", js:true do
-
visit "/"
-
sleep 1
-
click_button "Sign up for free"
-
sleep 1
-
page.save_screenshot 'Sign_up.png'
-
page.has_content? "form#new_user"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "back_to_colletion_button" do
-
-
1
it "should go back to collection", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'create_collection.png'
-
collection = create_collection_for (user)
-
create_site_for (collection)
-
login_as (user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
sleep 5
-
find('.pback').click
-
sleep 2
-
expect(page).to have_content ("Central Hospital")
-
expect(page).to have_content ("My Collections")
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "bulk_upload_fail" do
-
-
1
it "should NOT upload a bulk for a collection", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
sleep 2
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
sleep 2
-
click_link "Upload it for bulk sites updates"
-
sleep 2
-
page.has_content? ('#upload')
-
page.attach_file 'upload', 'sanitized_rwanda_schema.json'
-
expect(page).to have_content ('Invalid file format. Only CSV files are allowed.')
-
sleep 2
-
page.save_screenshot ("Upload bulk fail.png")
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "bulk_upload" do
-
-
1
it "should upload a bulk for a collection", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
-
sleep 5
-
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
-
sleep 5
-
-
click_link "Upload it for bulk sites updates"
-
sleep 3
-
page.has_content? ('#upload')
-
page.attach_file 'upload', 'Test Collection_sites.csv'
-
-
click_link "resmap-id"
-
-
page.find(:xpath, '//div[@id="columnUsageTemplate"]/div[1]/div/div[@class="popup-row"]/div[@class="left"][2]/select').click
-
-
select 'Ignore'
-
click_button "Apply"
-
-
click_button "Start importing"
-
sleep 3
-
expect(page).to have_content "Importing"
-
-
# click_link ('Collections')
-
# sleep 30
-
# page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
# sleep 25
-
-
-
# page.should have_content "Abbey"
-
# page.should have_content "Kratos"
-
-
sleep 2
-
-
page.save_screenshot ("Upload a bulk.png")
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "cancel_import" do
-
-
1
it "should cancel import", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
sleep 5
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
sleep 5
-
click_link "Upload it for bulk sites updates"
-
sleep 3
-
page.has_content? ('#upload')
-
page.attach_file 'upload', 'Test Collection_sites.csv'
-
click_link "resmap-id"
-
page.find(:xpath, '//div[@id="columnUsageTemplate"]/div[1]/div/div[@class="popup-row"]/div[@class="left"][2]/select').click
-
select 'Ignore'
-
click_button "Apply"
-
sleep 2
-
click_button "Start importing"
-
sleep 3
-
click_button "Cancel import"
-
sleep 2
-
expect(page).to have_content "Import canceled"
-
sleep 2
-
page.save_screenshot "Cancel_import.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "change_collections_icon" do
-
-
1
it " should change a collections icon", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Settings"
-
sleep 3
-
page.find(".army").click
-
sleep 2
-
click_button "Save"
-
page.save_screenshot "Edit Collections icon.png"
-
expect(page).to have_content "Collection Central Hospital updated"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "change_tab_activity" do
-
-
1
it "should change to activity tab", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
login_as (@user)
-
visit collections_path
-
click_link ('Activity')
-
sleep 3
-
page.save_screenshot 'TabActivity'
-
sleep 2
-
expect(page).to have_content ('Activity')
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "change_tab_home" do
-
-
1
it "should change to home tab", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="NavMenu"]/ul/li[2]/a').click
-
sleep 3
-
page.save_screenshot 'TabHome'
-
sleep 3
-
expect(page).to have_content ('Make better decisions')
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "check_collections_activity" do
-
-
1
it "should check collections activity", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(@user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
login_as (@user)
-
visit collections_path
-
click_link ('Activity')
-
sleep 3
-
page.save_screenshot 'TabActivity'
-
expect(page).to have_content ('Activity')
-
find(:xpath, "//div[@class='tabsline']/table/tbody/tr[2]/td[1]/span[2]").click
-
sleep 5
-
expect(page).to have_no_content ('mina@gutkowski.com')
-
sleep 5
-
find(:xpath, "//div[@class='tabsline']/table/tbody/tr[2]/td[1]/span[1]").click
-
sleep 10
-
page.has_content? ('mina@gutkowski.com')
-
page.save_screenshot 'check_collections_activity.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "check_events_activity" do
-
-
1
it "should check events activity", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(@user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
login_as (@user)
-
visit collections_path
-
click_link ('Activity')
-
sleep 3
-
page.save_screenshot 'TabActivity'
-
expect(page).to have_content ('Activity')
-
find(:xpath, "//div[@class='tabsline']/table/tbody/tr[2]/td[2]/span[2]").click
-
sleep 5
-
expect(page).to have_no_content ('mina@gutkowski.com')
-
sleep 5
-
find(:xpath, "//div[@class='tabsline']/table/tbody/tr[2]/td[2]/span[1]").click
-
sleep 10
-
page.has_content? ('mina@gutkowski.com')
-
sleep 2
-
page.save_screenshot 'Check_events_activity.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "clear_search" do
-
-
1
it "should clear search", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'filter_sites.png'
-
collection = create_collection_for (user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
10.times { collection.sites.make properties: { field.es_code => 'fra' } }
-
10.times { collection.sites.make properties: { field.es_code => 'ter' } }
-
10.times { collection.sites.make properties: { field.es_code => 'nity' } }
-
login_as (user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
fill_in 'search', :with => "Aida Rohan\n"
-
sleep 10
-
expect(page).to have_content 'Aida Rohan'
-
sleep 2
-
click_link 'clear search'
-
page.save_screenshot 'Clear_search.png'
-
expect(page).to have_content 'Alek Ortiz'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "create_collection" do
-
-
1
it "should not create a collection", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[3]/button').click
-
sleep 1
-
click_button "Save"
-
sleep 1
-
page.save_screenshot "Create Collection_fail.png"
-
expect(page).to have_content("Name can't be blank")
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "create_collection" do
-
-
1
it "should create a collection", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[3]/button').click
-
sleep 1
-
fill_in "collection_name", :with => 'Coleccion de prueba'
-
click_button "Save"
-
sleep 1
-
page.save_screenshot "Create Collection.png"
-
expect(page).to have_content("Collection Coleccion de prueba created")
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "create_site" do
-
-
1
it "should create a site", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_button 'Create Site'
-
fill_in 'name', :with => 'New site'
-
fill_in 'locationText', :with => '-37.991902, -57.602087'
-
click_button 'Done'
-
sleep 5
-
page.save_screenshot 'Create site.png'
-
expect(page).to have_content "Site 'New site' successfully created"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "snapshots" do
-
-
1
it "should not create site using snapshot", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(user)
-
snap= Snapshot.make :collection => collection
-
UserSnapshot.make :user => user, :snapshot => snap
-
login_as (user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr/td/div[2]/button').click
-
sleep 3
-
expect(page).not_to have_content "Create Site"
-
expect(page).to have_content "You are currently viewing this collection's data as it was on snapshot mina."
-
page.save_screenshot 'Create_site_with_snapshot.png'
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "create_snapshot_fail" do
-
-
1
it "should not take a snapshot", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
sleep 2
-
click_button 'Take new snapshot'
-
sleep 2
-
page.save_screenshot 'Create_snapshot_fail.png'
-
expect(page).to have_content "Name can't be blank"
-
expect(page).to have_content 'Snapshot could not be created'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "create_snapshot" do
-
-
1
it "should take a snapshot", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
fill_in 'snapshot_name', :with => 'Snapshot 1'
-
click_button 'Take new snapshot'
-
sleep 2
-
page.save_screenshot 'New snapshot.png'
-
expect(page).to have_content 'Snapshot 1'
-
expect(page).to have_content 'Snapshot created'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "delete_collection_sites" do
-
-
1
it "should delete sites of a collection", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Delete this collection's sites"
-
click_link "Confirm"
-
sleep 2
-
page.save_screenshot "Delete Collection Sites.png"
-
sleep 6
-
expect(page).to have_content "Collection Central Hospital's sites deleted"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "delete_collection" do
-
-
1
it "should delete a collection", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Delete collection"
-
click_link "Confirm"
-
page.save_screenshot "Delete Collection.png"
-
expect(page).to have_content "Collection Central Hospital deleted"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "delete_site" do
-
-
1
it "should delete site", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'create_collection.png'
-
collection = create_collection_for (user)
-
create_site_for (collection)
-
login_as (user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
sleep 3
-
click_link 'Delete Site'
-
sleep 3
-
page.driver.browser.switch_to.alert.accept
-
sleep 3
-
page.save_screenshot "Delete_site.png"
-
expect(page).to have_no_content ("Health Center")
-
end
-
end
-
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should change a collection name", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Settings"
-
fill_in "collection_name", :with => 'Mi Coleccion'
-
click_button "Save"
-
page.save_screenshot "Edit Collection.png"
-
expect(page).to have_content "Collection Mi Coleccion updated"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "edit_field" do
-
-
1
it "should edit field", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'edit_layer.png'
-
collection = create_collection_for(@user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Layers"
-
sleep 2
-
click_button "Edit"
-
sleep 2
-
fill_in 'field_name', :with => 'Test Field'
-
sleep 5
-
click_button 'Save layer'
-
sleep 5
-
page.save_screenshot 'Edit_field.png'
-
expect(page).to have_content "Layer 'Central Hospital Layer 1' successfully saved"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "edit_layer" do
-
-
1
it "should edit layer", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'edit_layer.png'
-
collection = create_collection_for(@user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Layers"
-
click_button "Edit"
-
fill_in 'Name', :with => 'Test Layer'
-
click_button 'Save layer'
-
page.save_screenshot 'Edit_layer.png'
-
expect(page).to have_content "Layer 'Test Layer' successfully saved"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "snapshots" do
-
-
1
it "should not edit layer with snapshot", js:true do
-
sleep 5
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
snap= Snapshot.make(:collection => collection, :name => 'Felurian')
-
UserSnapshot.make :user => user, :snapshot => snap
-
login_as (user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr/td/div[2]/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
sleep 2
-
choose ('name_Felurian')
-
sleep 2
-
click_link "Layers"
-
sleep 2
-
expect(page).not_to have_content "Edit"
-
sleep 2
-
expect(page).to have_content "You are currently viewing this collection's data as it was on snapshot Felurian. To make changes, please"
-
page.save_screenshot 'Edit_layer_snapshot.png'
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "sites" do
-
-
1
it "should edit site yes/no value", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
yes_no = layer.yes_no_fields.make(:name => 'Y/N', :code => 'y/n')
-
collection.sites.make properties: { yes_no.es_code => 1 }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
page.uncheck('yes-no-input-y/n')
-
click_button 'Done'
-
expect(page).not_to have_content ('yes')
-
expect(page).to have_content ('no')
-
page.save_screenshot "Edit_site_yes_no_value.png"
-
end
-
-
end
-
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site Text values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
email = layer.email_fields.make(:name => 'Email', :code => 'email')
-
collection.sites.make properties: { email.es_code => 'man@as.com' }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 2
-
fill_in 'email-input-email', :with => 'manas@manas.com'
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content 'man@as.com'
-
expect(page).to have_content 'manas@manas.com'
-
page.save_screenshot "Edit_site_Email_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site Identifier values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
identifier = layer.identifier_fields.make(:name => 'ID', :code => 'id')
-
collection.sites.make properties: { identifier.es_code => 'ID4567HJL' }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 3
-
fill_in 'identifier-input-id', :with => 'GB120712MB'
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content 'ID4567HJL'
-
expect(page).to have_content 'GB120712MB'
-
page.save_screenshot "Edit_site_identifier_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site Numeric values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
numeric = layer.numeric_fields.make(:name => 'Numeric', :code => 'numeric')
-
collection.sites.make properties: { numeric.es_code => '876' }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 2
-
fill_in 'numeric-input-numeric', :with => '1234567890'
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content '876'
-
expect(page).to have_content '1234567890'
-
page.save_screenshot "Edit_site_Numeric_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site phone values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
phone = layer.phone_fields.make(:name => 'Phone', :code => 'phone')
-
collection.sites.make properties: { phone.es_code => '1558769876' }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 2
-
find("input[placeholder='85512345678']").set "1157804274"
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content '1558769876'
-
sleep 2
-
expect(page).to have_content '1157804274'
-
sleep 2
-
page.save_screenshot "Edit_site_Phone_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "sites" do
-
-
1
it "should edit site Select many values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
select_many = layer.select_many_fields.make(:name => 'Select Many', :code => 'selmany', config: {"options"=>[{"id"=>1, "code"=>"firstopcod", "label"=>"first op"}, {"id"=>2, "code"=>"secopcod", "label"=>"second op"}, {"id"=>3, "code"=>"anotheropcod", "label"=>"another op"}], "next_id"=>4})
-
collection.sites.make :id => 8902, :name => 'Type: Select Many', properties: { select_many.es_code => [2,3] }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
expect(page).not_to have_content 'first'
-
click_link 'Edit Site'
-
sleep 5
-
find_by_id('Add more').click
-
fill_in 'select-many-input-selmany', :with => "first\n"
-
sleep 5
-
click_button 'Done'
-
sleep 5
-
expect(page).to have_content 'first'
-
page.save_screenshot "Edit_site_selman_value.png"
-
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site Select One values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
select_one = layer.select_one_fields.make(:name => 'Select One', :code => 'selone', config: {"options"=>[{"id"=>1, "code"=>"option code 1", "label"=>"first option"},{"id"=>2, "code"=>"option code 2", "label"=>"second option"}], "next_id"=>3})
-
collection.sites.make :name => 'Type: Select One', properties: { select_one.es_code => 2 }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 5
-
select('first option', :from => 'select-one-input-selone')
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content 'second option'
-
expect(page).to have_content 'first option'
-
page.save_screenshot "Edit_site_selone_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "sites" do
-
-
1
it "should edit site Site value", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
site_field = layer.site_fields.make(:name => 'Site', :code => 'site')
-
site1 = collection.sites.make :name => 'First Site'
-
collection.sites.make :name => 'Second Site'
-
collection.sites.make :name => 'Type: Site', properties: { site_field.es_code => site1.id }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[3]/td/button').click
-
expect(page).to have_content 'First Site'
-
expect(page).not_to have_content 'Second Site'
-
click_link 'Edit Site'
-
sleep 3
-
fill_in 'site-input-site', :with => "Second Site\n"
-
sleep 3
-
expect(page).not_to have_content 'First Site'
-
expect(page).to have_content 'Second Site'
-
page.save_screenshot "Edit_site_Site_value.png"
-
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "edit_site" do
-
-
1
it "edit site", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'create_collection.png'
-
collection = create_collection_for (user)
-
create_site_for (collection)
-
login_as (user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 2
-
fill_in 'locationText', :with => '-37.991902, -57.602087'
-
sleep 3
-
click_button 'Done'
-
sleep 4
-
expect(page).not_to have_content ('26.7574, 14.3574')
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site Text values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
text = layer.text_fields.make(:name => 'Text', :code => 'text')
-
collection.sites.make properties: { text.es_code => 'one text' }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 2
-
fill_in 'value', :with => 'Prueba'
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content 'one text'
-
expect(page).to have_content 'Prueba'
-
page.save_screenshot "Edit_site_Text_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site User values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
user_field = layer.user_fields.make(:name => 'User', :code => 'user')
-
collection.sites.make :name => 'Type: User', properties: { user_field.es_code => 'member@member.com' }
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 2
-
fill_in 'user-input-user', :with => 'user@manas.com.ar'
-
sleep 2
-
click_button 'Done'
-
sleep 3
-
expect(page).not_to have_content 'member@member.com'
-
sleep 2
-
expect(page).to have_content 'user@manas.com.ar'
-
sleep 2
-
page.save_screenshot "Edit_site_user_value.png"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "snapshots" do
-
-
1
it "should not edit site using snapshot", js:true do
-
# p "This test fails because https://bitbucket.org/instedd/resource_map/issue/401/displayed-number-of-snapshots-sites-is"
-
sleep 5
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (user)
-
create_site_for (collection)
-
snap= Snapshot.make :collection => collection
-
UserSnapshot.make :user => user, :snapshot => snap
-
login_as (user)
-
visit collections_path
-
sleep 3
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr/td/div[2]/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
sleep 3
-
expect(page).not_to have_content "Edit"
-
sleep 2
-
page.has_content? "You are currently viewing this collection's data as it was on snapshot mina. Go back to present "
-
# page.should have_content "You are currently viewing this collection's data as it was on snapshot mina. Go back to present"
-
sleep 2
-
page.save_screenshot 'Edit_site_snapshot.png'
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should edit site Text values", js:true do
-
-
current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for (current_user)
-
member = User.make(:email => 'member@member.com')
-
member.memberships.make collection: collection
-
layer = create_layer_for (collection)
-
date = layer.date_fields.make(:name => 'Date', :code => 'date')
-
collection.sites.make :name => 'Type: Date', properties: { date.es_code => '2013-04-06T00:00:00Z'}
-
login_as (current_user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
click_link 'Edit Site'
-
sleep 25
-
fill_in 'valueUI', :with => '12/7/2013'
-
click_button 'Done'
-
sleep 3
-
expect(page).to have_content '12/7/2013'
-
page.save_screenshot "Edit_site_Date_value.png"
-
end
-
end
-
# require 'spec_helper'
-
-
# describe "collections" do
-
-
# it "should edit site field values", js:true do
-
-
# current_user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
# collection = create_collection_for (current_user)
-
# member = User.make(:email => 'member@member.com')
-
# member.memberships.make collection: collection
-
# layer = create_layer_for (collection)
-
# text = layer.text_fields.make(:name => 'Text', :code => 'text')
-
# phone = layer.phone_fields.make(:name => 'Phone', :code => 'phone')
-
# email = layer.email_fields.make(:name => 'Email', :code => 'email')
-
# numeric = layer.numeric_fields.make(:name => 'Numeric', :code => 'numeric')
-
# user_field = layer.user_fields.make(:name => 'User', :code => 'user')
-
# hierarchy = layer.hierarchy_fields.make(:name => 'Hierarchy', :code => 'hierarchy', config: {"hierarchy"=>[{"order"=>"1", "id"=>"1000", "name"=>"madre", "sub"=>[{"order"=>"5", "id"=>"5000", "name"=>"tio"}, {"order"=>"6", "id"=>"6000", "name"=>"tia"}]}, {"order"=>"2", "id"=>"2000", "name"=>"padre", "sub"=>[{"order"=>"3", "id"=>"3000", "name"=>"hijo"}, {"order"=>"4", "id"=>"4000", "name"=>"hija"}]}]})
-
# select_one = layer.select_one_fields.make(:name => 'Select One', :code => 'selone', config: {"options"=>[{"id"=>1, "code"=>"option code 1", "label"=>"first option"},{"id"=>2, "code"=>"option code 2", "label"=>"second option"}], "next_id"=>3})
-
# select_many = layer.select_many_fields.make(:name => 'Select Many', :code => 'selmany', config: {"options"=>[{"id"=>1, "code"=>"firstopcod", "label"=>"first op"}, {"id"=>2, "code"=>"secopcod", "label"=>"second op"}, {"id"=>3, "code"=>"anotheropcod", "label"=>"another op"}], "next_id"=>4})
-
# yes_no = layer.yes_no_fields.make(:name => 'Yes No', :code => 'y/n')
-
# identifier = layer.identifier_fields.make(:name => 'ID', :code => 'id')
-
# date = layer.date_fields.make(:name => 'Date', :code => 'date')
-
# site = layer.site_fields.make(:name => 'Site', :code => 'site')
-
# collection.sites.make properties: { text.es_code => 'one text' }
-
# collection.sites.make properties: { numeric.es_code => '876' }
-
# collection.sites.make properties: { phone.es_code => '1558769876' }
-
# collection.sites.make properties: { email.es_code => 'man@as.com' }
-
# collection.sites.make :name => 'Type: User', properties: { user_field.es_code => 'member@member.com' }
-
# collection.sites.make :name => 'Type: Select One', properties: { select_one.es_code => 2 }
-
# collection.sites.make :id => 8902, :name => 'Type: Select Many', properties: { select_many.es_code => [2,3] }
-
# collection.sites.make properties: { yes_no.es_code => 1 }
-
# collection.sites.make properties: { identifier.es_code => 'ID4567HJL' }
-
# collection.sites.make :name => 'Type: Site', properties: { site.es_code => 8902 }
-
# collection.sites.make :name => 'Type: Date', properties: { date.es_code => '2013-04-06T00:00:00Z'}
-
# collection.sites.make :name => 'Type: Hierarchy', properties: { hierarchy.es_code => '5000'}
-
# login_as (current_user)
-
# visit collections_path
-
# find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
# sleep 5
-
# find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
# click_link 'Edit Site'
-
# sleep 5
-
# page.uncheck('yes-no-input-y/n')
-
# #fill_in 'yesno', :with => 'ESTO ES UN TEXTO'
-
# sleep 5
-
# click_button 'Done'
-
# sleep 5
-
# page.should_not have_content ('26.7574, 14.3574')
-
# end
-
-
# end
-
1
require 'spec_helper'
-
-
1
describe "filter_sites" do
-
-
1
it "should filter sites", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'filter_sites.png'
-
collection = create_collection_for (user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
10.times { collection.sites.make properties: { field.es_code => 'fra' } }
-
10.times { collection.sites.make properties: { field.es_code => 'ter' } }
-
10.times { collection.sites.make properties: { field.es_code => 'nity' } }
-
login_as (user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
find('.refine').click
-
find(:xpath, '//div[@class="refine-popup box"]/div[3]').click
-
sleep 2
-
find(:xpath, '//div[@class="refine-popup box"]/div[4]/input').set("fra")
-
sleep 2
-
find(:xpath, '//div[@class="refine-popup box"]/div[4]/a').click
-
sleep 3
-
expect(page).to have_content 'Show sites where Central Hospital Layer 1 Field starts with "fra" '
-
page.save_screenshot 'Filter_sites.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "load_snapshot" do
-
-
1
it "should load a snapshot", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
fill_in 'snapshot_name', :with => 'Snapshot2'
-
click_button 'Take new snapshot'
-
sleep 2
-
expect(page).to have_content 'Snapshot2'
-
choose ('name_Snapshot2')
-
sleep 1
-
page.save_screenshot "Load snapshot"
-
expect(page).to have_content 'Snapshot Snapshot2 loaded'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "navigate_map" do
-
-
1
it "should navigate map", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[2]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[2]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[2]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[3]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[3]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[3]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[1]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[1]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[1]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[4]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[4]').click
-
sleep 1
-
find(:xpath, '//div/div[@class="gmnoprint"][3]/div[@class="gmnoprint"][1]/div[@class="gmnoprint"][2]/div/div[4]').click
-
sleep 2
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "search" do
-
-
1
it "should search", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
page.save_screenshot 'filter_sites.png'
-
collection = create_collection_for (user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
10.times { collection.sites.make properties: { field.es_code => 'fra' } }
-
10.times { collection.sites.make properties: { field.es_code => 'ter' } }
-
10.times { collection.sites.make properties: { field.es_code => 'nity' } }
-
login_as (user)
-
visit collections_path
-
find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
fill_in 'search', :with => "Aida Rohan\n"
-
sleep 5
-
page.save_screenshot 'Search.png'
-
sleep 3
-
page.has_content? 'Aida Rohan'
-
sleep 3
-
expect(page).to have_no_content 'Alek Ortiz'
-
sleep 2
-
end
-
end
-
-
-
1
require 'spec_helper'
-
-
1
describe "members" do
-
-
1
it "should add member", js:true do
-
admin = User.make(:email => 'admin@admin.com')
-
collection = create_collection_for(admin)
-
user = User.make(:email => 'member@member.com')
-
# user.memberships.make collection: collection, admin: false
-
login_as (admin)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Members"
-
fill_in "member_email", :with => "member@member.com"
-
page.find(:xpath, '//div[@id="autocomplete_container"]/ul/li/a').click
-
sleep 3
-
expect(page).to have_content 'member@member.com'
-
page.save_screenshot 'Add member.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "members" do
-
-
1
it "should give admin rights", js:true do
-
admin = User.make(:email => 'admin@admin.com')
-
collection = create_collection_for(admin)
-
user = User.make(:email => 'member@member.com')
-
user.memberships.make collection: collection, admin: false
-
login_as (user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
expect(page).not_to have_content "Members"
-
find_by_id('User').click
-
click_link('Sign Out')
-
sleep 3
-
login_as (admin)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Members"
-
find(:xpath, '//div[@id="container"]/div[2]/table/tbody/tr[3]/td/div/div[5]/input').click
-
find_by_id('User').click
-
click_link('Sign Out')
-
sleep 3
-
login_as (user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
sleep 2
-
page.save_screenshot 'Members.png'
-
expect(page).to have_content "Members"
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "members" do
-
-
1
it "should remove member", js:true do
-
admin = User.make(:email => 'admin@admin.com')
-
collection = create_collection_for(admin)
-
user = User.make(:email => 'member@member.com')
-
user.memberships.make collection: collection, admin: false
-
login_as (admin)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Members"
-
page.find(:xpath, '//div[@id="container"]/div[2]/table/tbody/tr[3]/td/div/div[1]/img').click
-
page.find(:xpath, '//div[@class="memberHeaderColumn"]/a[@class="icon fdelete black"]').click
-
page.find(:xpath, '//div[@class="sbox grey"]/div[3]/a[@class="button white right"]').click
-
expect(page).to have_no_content ('member@member.com')
-
page.save_screenshot 'Remove_member.png'
-
sleep 3
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "layers" do
-
-
1
it "should sort layer", js:true do
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(user)
-
layers = %w{ Beds Rooms }
-
layers.each do |layer|
-
lay = collection.layers.make(:name => layer)
-
lay.text_fields.make
-
end
-
login_as (user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
click_link "Layers"
-
click_button "Move layer down"
-
page.find(:xpath, '//div[@id="layers-main"]/div[1]/button').click
-
expect(page).to have_content layers[0]
-
page.save_screenshot 'Sort_layer.png'
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "collections" do
-
-
1
it "should switch snapshots", js:true do
-
-
user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(user)
-
snapshots = %w{ jan feb march april may }
-
snapshots.each do |snapshot|
-
snap= Snapshot.make :collection => collection, :name => snapshot
-
UserSnapshot.make :user => user, :snapshot => snap
-
end
-
login_as (user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr/td/div[2]/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
sleep 3
-
choose ('name_feb')
-
sleep 3
-
expect(page).to have_content 'Snapshot feb loaded'
-
page.save_screenshot "Switch_snapshot.png"
-
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe "uncheck_collections_activity" do
-
-
1
it "should uncheck collections activity", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(@user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
login_as (@user)
-
visit collections_path
-
click_link ('Activity')
-
sleep 3
-
page.save_screenshot 'TabActivity'
-
expect(page).to have_content ('Activity')
-
find(:xpath, "//div[@class='tabsline']/table/tbody/tr[2]/td[1]/span[2]").click
-
sleep 5
-
expect(page).to have_no_content ('mina@gutkowski.com')
-
page.save_screenshot 'Uncheck collections_activity.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "uncheck_events_activity" do
-
-
1
it "should uncheck events activity", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(@user)
-
layer = create_layer_for (collection)
-
field = create_field_for (layer)
-
login_as (@user)
-
visit collections_path
-
click_link ('Activity')
-
sleep 3
-
page.save_screenshot 'TabActivity'
-
expect(page).to have_content ('Activity')
-
find(:xpath, "//div[@class='tabsline']/table/tbody/tr[2]/td[2]/span[2]").click
-
sleep 5
-
expect(page).to have_no_content ('mina@gutkowski.com')
-
page.save_screenshot 'Uncheck events_activity.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "unload_snapshot" do
-
-
1
it "should go back to present time", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[2]/table/tbody/tr[1]/td/button').click
-
page.find(:xpath, '//div[@id="collections-main"]/div[1]/div[1]/button[2]').click
-
fill_in 'snapshot_name', :with => 'Snapshot3'
-
click_button 'Take new snapshot'
-
sleep 2
-
expect(page).to have_content 'Snapshot3'
-
choose ('name_Snapshot3')
-
sleep 1
-
expect(page).to have_content 'Snapshot Snapshot3 loaded'
-
choose ('name_')
-
sleep 1
-
page.save_screenshot ('Present_time.png')
-
expect(page).to have_content ('Snapshot Snapshot3 unloaded')
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "view_collections" do
-
-
1
it "should display view_collections", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit "/?explicit=true"
-
click_button ("View your collections")
-
sleep 3
-
expect(page).to have_content ("Central Hospital")
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "view_full_screen" do
-
-
1
it "should change to full screen view", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
find(:xpath, '//div[@id="right-panel"]/div[1]/button[1]').click
-
sleep 2
-
page.has_content?("icon_button right frestore")
-
sleep 2
-
page.save_screenshot 'Full screen view.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "view_table_mode" do
-
-
1
it "should change to table mode view", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
@collection = create_collection_for(@user)
-
login_as (@user)
-
visit collections_path
-
sleep 2
-
find(:xpath, '//div[@id="right-panel"]/div[1]/button[2]').click
-
sleep 2
-
has_content?("icon_button ftable right active")
-
sleep 2
-
page.save_screenshot 'Table view.png'
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "zoom in and out" do
-
-
1
it "should zoom in and out", js:true do
-
@user = User.make(:email => 'user@manas.com.ar', :password => '1234567', :phone_number => '855123456789')
-
collection = create_collection_for(@user)
-
create_site_for (collection)
-
login_as (@user)
-
visit collections_path
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[4]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[4]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[4]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[4]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[4]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[4]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[1]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[1]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[1]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[1]/img").click
-
find(:xpath, "//div[@id='map']/div/div[@class='gmnoprint'][3]/div[@class='gmnoprint'][3]/div[1]/img").click
-
end
-
end
-
# encoding = UTF-8
-
1
require 'spec_helper'
-
1
require 'polyglot'
-
1
require File.expand_path(File.join(File.dirname(__FILE__), 'treetop_helper'))
-
-
1
Treetop.load 'lib/treetop/command'
-
-
1
describe CommandParser do
-
1
before(:all) do
-
1
@parser = CommandParser.new
-
end
-
-
1
it "should parse query command with dyrm prefix" do
-
1
node = @parser.parse('dyrm q 1 beds>10')
-
1
expect(node.command).to be_is_a QueryCommandNode
-
1
expect(node.command.collection_id.value).to eq(1)
-
-
1
condition = node.command.conditional_expression
-
1
expect(condition.name.text_value).to eq('beds')
-
1
expect(condition.operator.text_value).to eq('>')
-
1
expect(condition.value.value).to eq(10)
-
end
-
-
1
it "should parse query command with dyrm prefix and '\\n' suffix" do
-
1
node = @parser.parse("dyrm q 1 beds>10\n")
-
1
expect(node.command).to be_is_a QueryCommandNode
-
end
-
-
1
it "should parse query command with dyrm prefix and space previous '\\n' suffix" do
-
1
node = @parser.parse("dyrm q 1 beds>10 \n")
-
1
expect(node.command).to be_is_a QueryCommandNode
-
end
-
-
1
it "should parse query command with dyrm prefix and '\\r' suffix" do
-
1
node = @parser.parse("dyrm q 1 beds>10\r")
-
1
expect(node.command).to be_is_a QueryCommandNode
-
end
-
-
1
it "should parse query command with dyrm prefix and space previous '\\r' suffix" do
-
1
node = @parser.parse("dyrm q 1 beds>10 \r")
-
1
expect(node.command).to be_is_a QueryCommandNode
-
end
-
-
1
it "should parse query command with dyrm prefix and '\\n\\r' suffix" do
-
1
node = @parser.parse("dyrm q 1 beds>10\n\r")
-
1
expect(node.command).to be_is_a QueryCommandNode
-
end
-
-
1
it "should parse query command with dyrm prefix and space previos '\\n\\r' suffix" do
-
1
node = @parser.parse("dyrm q 1 beds>10\n\r")
-
1
expect(node.command).to be_is_a QueryCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix" do
-
1
node = @parser.parse('dyrm u AA111 beds=222,doctors=55')
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
1
expect(node.command.resource_id.text_value).to eq('AA111')
-
-
1
properties = node.command.property_list
-
1
first = properties.assignment_expression
-
1
expect(first.name.text_value).to eq("beds")
-
1
expect(first.value.value).to eq(222)
-
-
1
second = properties.next
-
1
expect(second.name.text_value).to eq("doctors")
-
1
expect(second.value.value).to eq(55)
-
end
-
-
1
it "should parse update command with dyrm prefix and 1 comma suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222,")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and many comma suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222,")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and '\\n' suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222\n")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and space previous '\\n' suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222 \n")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and '\\r' suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222\r")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and space previous '\\r' suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222 \r")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and '\\n\\r' suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222\n\r")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse update command with dyrm prefix and space previous '\\n\\r' suffix" do
-
1
node = @parser.parse("dyrm u AA111 beds=222 \n\r")
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
end
-
-
1
it "should parse query command with equal condition" do
-
1
node = @parser.parse('dyrm q 1 pname=kandal')
-
1
expect(node.command).to be_is_a QueryCommandNode
-
1
expect(node.command.collection_id.value).to eq(1)
-
-
1
condition = node.command.conditional_expression
-
1
expect(condition.name.text_value).to eq('pname')
-
1
expect(condition.operator.text_value).to eq('=')
-
1
expect(condition.value.text_value).to eq('kandal')
-
end
-
-
1
it "should parse update command with condition value as string" do
-
1
node = @parser.parse('dyrm u AB123 pname=foo123')
-
1
expect(node.command).to be_is_a UpdateCommandNode
-
1
expect(node.command.resource_id.text_value).to eq('AB123')
-
-
1
property = node.command.property_list
-
1
expect(property.name.text_value).to eq("pname")
-
1
expect(property.value.text_value).to eq("foo123")
-
end
-
-
1
describe "Query command node" do
-
1
it "should parse query command" do
-
1
node = @parser.parse('q 1 beds>8', :root => 'query_command')
-
1
expect(node).to be_is_a QueryCommandNode
-
1
expect(node.collection_id.value).to eq(1)
-
1
condition = node.conditional_expression
-
1
expect(condition.name.text_value).to eq('beds')
-
1
expect(condition.operator.text_value).to eq('>')
-
1
expect(condition.value.value).to eq(8)
-
end
-
end
-
-
1
describe "Update command node" do
-
1
it "should parse update command" do
-
1
node = @parser.parse('u AA888 foo=123, bar=bar', :root => 'update_command')
-
1
expect(node).to be_is_a UpdateCommandNode
-
1
expect(node.resource_id.text_value).to eq('AA888')
-
1
properties = node.property_list
-
1
first = properties.assignment_expression
-
1
expect(first.name.text_value).to eq('foo')
-
1
expect(first.value.value).to eq(123)
-
-
1
second = properties.next
-
1
expect(second.name.text_value).to eq('bar')
-
1
expect(second.value.text_value).to eq('bar')
-
end
-
end
-
-
1
describe "Expression nodes" do
-
1
it "should parse conditional expression" do
-
1
node = @parser.parse('foo>18', :root => 'conditional_expression')
-
1
expect(node).to be_is_a ConditionalExpressionNode
-
1
expect(node.name.text_value).to eq('foo')
-
1
expect(node.operator.text_value).to eq('>')
-
1
expect(node.value.value).to eq(18)
-
end
-
-
1
it "should parse condition expression with spaces" do
-
1
node = @parser.parse('name == foo ', :root => 'conditional_expression')
-
1
expect(node).to be_is_a ConditionalExpressionNode
-
1
expect(node.name.text_value).to eq('name')
-
1
expect(node.operator.text_value).to eq('==')
-
1
expect(node.value.text_value).to eq('foo ')
-
end
-
-
1
it "should parse assignment expression" do
-
1
node = @parser.parse('age=18', :root => 'assignment_expression')
-
1
expect(node).to be_is_a AssignmentExpressionNode
-
1
expect(node.name.text_value).to eq('age')
-
1
expect(node.value.value).to eq(18)
-
end
-
-
1
it "should parse assignment expression with spaces" do
-
1
node = @parser.parse('foo = bar ', :root => 'assignment_expression')
-
1
expect(node).to be_is_a AssignmentExpressionNode
-
1
expect(node.name.text_value).to eq('foo')
-
1
expect(node.value.text_value).to eq('bar ')
-
end
-
-
1
it "should parse 2 property list expression" do
-
1
node = @parser.parse('foo= 2, bar = 3abc', :root => 'property_list')
-
1
expect(node).not_to be_nil
-
-
1
first = node.assignment_expression
-
1
expect(first.name.text_value).to eq('foo')
-
1
expect(first.value.text_value).to eq('2')
-
-
1
second = node.next
-
1
expect(second.name.text_value).to eq('bar')
-
1
expect(second.value.text_value).to eq('3abc')
-
end
-
-
1
it "should parse unicode character" do
-
1
node = @parser.parse('u', :root => 'character')
-
1
expect(node).not_to be_nil
-
end
-
-
1
it "should not parse symbol as character" do
-
1
node = @parser.parse(':', :root => 'character')
-
1
expect(node).to be_nil
-
end
-
end
-
-
1
describe "Elementary nodes" do
-
1
it "should parse space" do
-
1
node = @parser.parse(' '*5, :root => 'space')
-
1
expect(node.text_value).to eq(' '*5)
-
end
-
-
1
it "should parse comparison operator" do
-
1
assert_comparison_node '>='
-
1
assert_comparison_node '<='
-
1
assert_comparison_node '=='
-
1
assert_comparison_node '='
-
1
assert_comparison_node '>'
-
1
assert_comparison_node '<'
-
end
-
-
1
it "should parse number with prefix 0" do
-
1
node = @parser.parse('0123', :root => 'number')
-
1
expect(node).to be_is_a NumberNode
-
end
-
-
1
it "should parse number 123" do
-
1
node = @parser.parse('123', :root => 'number')
-
1
expect(node).to be_is_a NumberNode
-
end
-
-
1
it "should parse symbol" do
-
1
assert_symbol_node '.'
-
1
assert_symbol_node '?'
-
1
assert_symbol_node ':'
-
1
assert_symbol_node ';'
-
1
assert_symbol_node '-'
-
1
assert_symbol_node '_'
-
1
assert_symbol_node '+'
-
1
assert_symbol_node '!'
-
1
assert_symbol_node '@'
-
1
assert_symbol_node '$'
-
1
assert_symbol_node '%'
-
1
assert_symbol_node '&'
-
1
assert_symbol_node '*'
-
1
assert_symbol_node '|'
-
1
assert_symbol_node '\\'
-
1
assert_symbol_node '/'
-
1
assert_symbol_node '('
-
1
assert_symbol_node ')'
-
1
assert_symbol_node '{'
-
1
assert_symbol_node '}'
-
1
assert_symbol_node '['
-
1
assert_symbol_node ']'
-
1
assert_symbol_node '"'
-
1
assert_symbol_node '\''
-
end
-
-
1
it "should parse phrase" do
-
1
node = @parser.parse('This is a phrase.', :root => 'phrase')
-
1
expect(node.text_value).to eq('This is a phrase.')
-
end
-
-
1
it "should parse phrase with symbol in the middle and separated by space" do
-
1
node = @parser.parse('10 - 10', :root => 'phrase')
-
1
expect(node).not_to be_nil
-
end
-
-
1
it "should parse phrase with 2 numbers separated by space" do
-
1
node = @parser.parse('10 10', :root => 'phrase')
-
1
expect(node).not_to be_nil
-
1
expect(node.text_value).to eq('10 10')
-
end
-
-
1
it "should parse string" do
-
1
assert_string_node 'abc'
-
end
-
-
1
it "should parse string follow by number as string" do
-
1
assert_string_node 'abc123'
-
end
-
-
1
it "should parse string with space" do
-
1
assert_string_node 'test me with more text'
-
end
-
-
1
it "should parse string prefix by number as string" do
-
1
assert_string_node '123abc wer'
-
end
-
-
1
it "should parse number by value rule" do
-
1
node = @parser.parse('999', :root => 'value')
-
1
expect(node).to be_is_a NumberNode
-
end
-
-
1
it "should parse string with symbol as string" do
-
1
node = @parser.parse('10--10', :root => 'word')
-
1
expect(node).not_to be_nil
-
end
-
-
1
it "should parse dyrm" do
-
1
expect(@parser.parse('dyrm', :root => 'dyrm')).not_to be_nil
-
1
expect(@parser.parse('Dyrm', :root => 'dyrm')).not_to be_nil
-
1
expect(@parser.parse('dYrm', :root => 'dyrm')).not_to be_nil
-
1
expect(@parser.parse('dyRm', :root => 'dyrm')).not_to be_nil
-
1
expect(@parser.parse('dyrM', :root => 'dyrm')).not_to be_nil
-
1
expect(@parser.parse('DYRM', :root => 'dyrm')).not_to be_nil
-
1
expect(@parser.parse('DyRM', :root => 'dyrm')).not_to be_nil
-
end
-
end
-
-
1
def assert_comparison_node(operator)
-
6
node = @parser.parse(operator, :root => 'comparison_operator')
-
6
expect(node.text_value).to eq(operator)
-
end
-
-
1
def assert_string_node(s)
-
4
node = @parser.parse(s, :root => 'value')
-
4
expect(node.text_value).to eq(s)
-
end
-
-
1
def assert_symbol_node(s)
-
24
node = @parser.parse(s, :root => 'symbol')
-
24
expect(node.text_value).to eq(s)
-
end
-
end
-
1
require 'spec_helper'
-
1
require File.expand_path(File.join(File.dirname(__FILE__), 'treetop_helper'))
-
-
1
describe ExecVisitor, "Process query command" do
-
1
before(:all) do
-
1
@visitor = ExecVisitor.new
-
end
-
-
1
before(:each) do
-
14
parser = CommandParser.new
-
14
@collection = Collection.make(:name => 'Healt Center')
-
14
@layer = @collection.layers.make(:name => "default")
-
14
@user = User.make(:phone_number => '85512345678')
-
14
@f1 = @layer.numeric_fields.make :id => 10, :name => "Ambulance", :code => "AB", :ord => 1
-
14
@f2 = @layer.numeric_fields.make :id => 11, :name => "Doctor", :code => "DO", :ord => 2
-
14
@collection.layer_memberships.create(:user => @user, :layer_id => @layer.id, :read => true, :write => true)
-
14
@collection.memberships.create(:user => @user, :admin => false)
-
-
14
@node = parser.parse("dyrm q #{@collection.id} AB>5").command
-
14
@node.sender = @user
-
14
@properties =[{:code=>"AB", :value=>"26"}]
-
end
-
-
1
it "should recognize collection_id equals to @collection.id" do
-
1
expect(@node.collection_id.value).to eq(@collection.id)
-
end
-
-
1
it "should recognize property name equals to AB" do
-
1
expect(@node.conditional_expression.name.text_value).to eq('AB')
-
end
-
-
1
it "should recognize conditional operator equals to greater than sign" do
-
1
expect(@node.conditional_expression.operator.text_value).to eq('>')
-
end
-
-
1
it "should recognize property value equals to 5" do
-
1
expect(@node.conditional_expression.value.value).to eq(5)
-
end
-
-
1
it "should find collection by id" do
-
1
expect(Collection).to receive(:find_by_id).with(@collection.id).and_return(@collection)
-
1
@visitor.visit_query_command @node
-
end
-
-
1
it "should user can view collection" do
-
1
expect(@visitor.can_view?(@properties[0], @node.sender, @collection)).to be_truthy
-
end
-
-
1
it "should query resources with condition options" do
-
1
expect(Collection).to receive(:find_by_id).with(@collection.id).and_return(@collection)
-
1
expect(@collection).to receive(:query_sites).with({ :code => 'AB', :operator => '>', :value => '5'})
-
1
@visitor.visit_query_command @node
-
end
-
-
1
describe "Reply message" do
-
1
context "valid criteria" do
-
1
it "should get Siemreap Health Center when their Ambulance property greater than 5" do
-
1
@collection.sites.make(:name => 'Siemreap Healt Center', :properties => {"10"=>15, "11"=>40})
-
1
expect(@visitor.visit_query_command(@node)).to eq('["AB"] in Siemreap Healt Center=15')
-
end
-
-
1
it "should return no result for public collection" do
-
1
@collection.public = true and @collection.save
-
1
expect(@visitor.visit_query_command(@node)).to eq("[\"AB\"] in There is no site matched")
-
end
-
end
-
-
1
context "invalid criteria" do
-
1
before(:each) do
-
4
@bad_user = User.make :phone_number => "222"
-
end
-
-
1
it "should return 'No resource available' when collection does not have any site" do
-
1
expect(@visitor.visit_query_command(@node)).to eq("[\"AB\"] in There is no site matched")
-
end
-
-
1
it "should return 'No site available' when site_properties does not match with condition" do
-
1
site = Site.make(:collection => @collection)
-
1
expect(@visitor.visit_query_command(@node)).to eq("[\"AB\"] in There is no site matched")
-
end
-
-
1
it "should raise error when the sender is not a dyrm user" do
-
1
@node.sender = nil
-
1
expect {
-
1
@visitor.visit_query_command(@node)
-
}.to raise_error(RuntimeError, ExecVisitor::MSG[:can_not_query])
-
end
-
-
1
it "should raise error when the sender is not a collection member" do
-
1
@node.sender = @bad_user
-
1
expect {
-
1
@visitor.visit_query_command(@node)
-
}.to raise_error(RuntimeError, ExecVisitor::MSG[:can_not_query])
-
end
-
end
-
-
1
context "when property value is not a number" do
-
1
before(:each) do
-
1
parser = CommandParser.new
-
1
@node = parser.parse("dyrm q #{@collection.id} PN=Phnom Penh").command
-
1
@node.sender = @user
-
end
-
-
1
it "should query property pname equals to Phnom Penh" do
-
1
@layer.text_fields.make :id => 22, :name => "pname", :code => "PN", :ord => 1
-
1
@collection.sites.make :name => 'Bayon', :properties => {"22"=>"Phnom Penh"}
-
1
expect(@visitor.visit_query_command(@node)).to eq "[\"PN\"] in Bayon=Phnom Penh"
-
end
-
end
-
end
-
end
-
-
1
describe ExecVisitor, "Process update command" do
-
1
before(:all) do
-
1
@visitor = ExecVisitor.new
-
end
-
13
let!(:options) { [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}] }
-
1
before(:each) do
-
12
@parser = CommandParser.new
-
12
@collection = Collection.make
-
12
@user = User.make(:phone_number => '85512345678')
-
12
@collection.memberships.create(:user => @user, :admin => true)
-
12
@layer = @collection.layers.make(:name => "default")
-
12
@f1 = @layer.numeric_fields.make(:id => 22, :code => "ambulances", :name => "Ambulance", :ord => 1)
-
12
@f2 = @layer.numeric_fields.make(:id => 23, :code => "doctors", :name => "Doctor", :ord => 1)
-
12
@f3 = @layer.select_many_fields.make(:id => 24, code: 'many', config: {'options' => options})
-
12
@site = @collection.sites.make(:name => 'Siemreap Healt Center', :properties => {"22"=>5, "23"=>2}, :id_with_prefix => "AB1")
-
12
@site.user = @user
-
12
@collection.layer_memberships.create(:user => @user, :layer_id => @layer.id, :read => true, :write => true)
-
12
@node = @parser.parse('dyrm u AB1 ambulances=15,doctors=20').command
-
12
@node.sender = @user
-
end
-
-
1
it "should recognize resource_id equals to AB1" do
-
1
expect(@node.resource_id.text_value).to eq('AB1')
-
end
-
-
1
it "should recognize first property setting ambulances to 15" do
-
1
property = @node.property_list.assignment_expression
-
1
expect(property.name.text_value).to eq('ambulances')
-
1
expect(property.value.value).to eq(15)
-
end
-
-
1
it "should recognize second property setting doctors to 20" do
-
1
property = @node.property_list.next
-
1
expect(property.name.text_value).to eq('doctors')
-
1
expect(property.value.value).to eq(20)
-
end
-
-
1
it "should find resource with id AB1" do
-
1
expect(Site).to receive(:find_by_id_with_prefix).with('AB1')
-
1
expect {
-
1
@visitor.visit_update_command @node
-
}.to raise_error
-
end
-
-
1
it "should user can update resource" do
-
1
expect(@visitor.can_update?(@node.property_list, @node.sender, @site)).to be_truthy
-
end
-
-
1
it "should validate sender can not update resource" do
-
1
sender = User.make(:phone_number => "111")
-
1
expect(@visitor.can_update?(@node.property_list, sender, @site)).to be_falsey
-
end
-
-
1
it "should raise exception when do not have permission" do
-
1
site = Site.make
-
1
expect(Site).to receive(:find_by_id_with_prefix).with('AB1').and_return(site)
-
-
1
@node.sender = User.make(:phone_number => '123')
-
1
expect {
-
1
@visitor.visit_update_command(@node)
-
}.to raise_error(RuntimeError, ExecVisitor::MSG[:no_rights_not_update] )
-
end
-
-
1
it "should update property of the site" do
-
1
expect(Site).to receive(:find_by_id_with_prefix).with('AB1').and_return(@site)
-
1
expect(@visitor).to receive(:can_update?).and_return(true)
-
1
expect(@visitor).to receive(:update_properties).with(@site, @node.sender, [{:code=>"ambulances", :value=>"15"}, {:code=>"doctors", :value=>"20"}])
-
1
expect(@visitor.visit_update_command(@node)).to eq(ExecVisitor::MSG[:update_successfully])
-
end
-
-
1
it "should update field Ambulance to 15 and Doctor to 20" do
-
1
expect(@visitor.visit_update_command(@node)).to eq(ExecVisitor::MSG[:update_successfully])
-
1
site = Site.find_by_id_with_prefix('AB1')
-
1
expect(site.properties[@f1.es_code].to_i).to eq(15)
-
1
expect(site.properties[@f2.es_code].to_i).to eq(20)
-
end
-
-
1
it "should update site name to test" do
-
1
@node = @parser.parse("dyrm u AB1 name=test").command
-
1
@node.sender = @user
-
1
expect(Site).to receive(:find_by_id_with_prefix).with('AB1').and_return(@site)
-
1
expect(@visitor).to receive(:can_update?).and_return(true)
-
1
expect(@visitor).to receive(:update_properties).with(@site, @node.sender, [{:code=>"name", :value=>"test"}])
-
1
expect(@visitor.visit_update_command(@node)).to eq(ExecVisitor::MSG[:update_successfully])
-
end
-
-
1
it "should update field many to [1,2]" do
-
1
@node = @parser.parse("dyrm u AB1 many=one&two").command
-
1
@node.sender = @user
-
1
expect(@visitor.visit_update_command(@node)).to eq(ExecVisitor::MSG[:update_successfully])
-
1
site = Site.find_by_id_with_prefix('AB1')
-
1
expect(site.properties[@f3.es_code]).to eq([1,2])
-
end
-
-
1
it 'should return cannot find site id when trying to update a site that does not exist' do
-
1
@node11 = @parser.parse('dyrm u 44 ambulances=15').command
-
2
expect{@visitor.visit_update_command(@node11)}.to raise_error(ExecVisitor::MSG[:can_not_find_site]+'44')
-
end
-
-
end
-
-
-
1
describe ExecVisitor, "Process add command" do
-
1
before(:all) do
-
1
@visitor = ExecVisitor.new
-
1
@parser = CommandParser.new
-
end
-
15
let!(:options) { [{'id' => 1, 'code' => '1', 'label' => 'One'}, {'id' => 2, 'code' => '2', 'label' => 'Two'}] }
-
1
before(:each) do
-
14
@collection = Collection.make
-
14
@user = User.make(:phone_number => '85512345679')
-
14
@collection.memberships.create(:user => @user, :admin => true)
-
14
@layer = @collection.layers.make(:name => "default")
-
14
@f1 = @layer.numeric_fields.make(:id => 22, :code => "ambulances", :name => "Ambulance", :ord => 1, :kind => "numeric")
-
14
@f2 = @layer.numeric_fields.make(:id => 23, :code => "doctors", :name => "Doctor", :ord => 1, :kind => "numeric")
-
14
@f3 = @layer.select_many_fields.make code: 'many', config: {'options' => options}
-
#@site = @collection.sites.make(:name => 'Siemreap Healt Center', :properties => {"22"=>5, "23"=>2}, :id_with_prefix => "AB1")
-
#@collection.layer_memberships.create(:user => @user, :layer_id => @layer.id, :read => true, :write => true)
-
14
@node = @parser.parse("dyrm a #{@collection.id} lat=12.11,lng=75.11,name=sms_site").command
-
14
@node.sender = @user
-
end
-
-
1
it 'should have collection_id' do
-
1
expect(@node.collection_id.value).to eq(@collection.id)
-
end
-
-
1
it 'should recognize lat equal 12.11' do
-
1
property = @node.property_list.assignment_expression
-
1
expect(property.name.text_value).to eq 'lat'
-
1
expect(property.value.text_value).to eq '12.11'
-
end
-
-
1
it 'should recognize lng equal 75.11' do
-
1
property = @node.property_list.next.assignment_expression
-
1
expect(property.name.text_value).to eq 'lng'
-
1
expect(property.value.text_value).to eq '75.11'
-
end
-
-
1
it 'should recognize name equal sms_site ' do
-
1
property = @node.property_list.next.next
-
1
expect(property.name.text_value).to eq 'name'
-
1
expect(property.value.text_value).to eq 'sms_site'
-
end
-
-
1
it 'should return added_successfully after site has been created' do
-
1
expect(@visitor.visit_add_command(@node)).to eq(ExecVisitor::MSG[:added_successfully])
-
end
-
-
1
it 'should added 1 new site when visit_add_command called' do
-
1
@node = @parser.parse("dyrm a #{@collection.id} lat=12.11,lng=75.11,name=sms_site,doctors=10").command
-
1
@node.sender = @user
-
2
expect{@visitor.visit_add_command(@node)}.to change{
-
2
Collection.find(@collection.id).sites.count
-
}.by(1)
-
end
-
-
1
it 'should add 1 new site with select many field when select many code exist' do
-
1
@node = @parser.parse("dyrm a #{@collection.id} lat=12.11,lng=75.11,name=sms_site,doctors=10,many=2&1").command
-
1
@node.sender = @user
-
1
sites = Collection.find(@collection.id).sites
-
2
expect{@visitor.visit_add_command(@node)}.to change{
-
2
sites.count
-
}.by(1)
-
end
-
-
1
it 'should return added_successfully without collection_id' do
-
1
@node = @parser.parse("dyrm a lat=12.11,lng=75.11,name=sms_site").command
-
1
@node.sender = @user
-
1
expect(@visitor.visit_add_command(@node)).to eq(ExecVisitor::MSG[:added_successfully])
-
end
-
-
1
it 'should return collection_id is needed when sender have more than 1 collections' do
-
1
@collection1 = Collection.make
-
1
@collection1.memberships.create(:user => @user, :admin => false)
-
1
@node = @parser.parse("dyrm a lat=12.11,lng=75.11,name=sms_site").command
-
1
@node.sender = @user
-
1
expect(@visitor.visit_add_command(@node)).to eq "Collection id is needed in your message."
-
end
-
-
1
it 'should return collection_id is needed when sender do not belong to any collections' do
-
1
@user1 = User.make(:phone_number => '85512345678')
-
1
@node = @parser.parse("dyrm a lat=12.11,lng=75.11,name=sms_site").command
-
1
@node.sender = @user1
-
1
expect(@visitor.visit_add_command(@node)).to eq "Collection id is needed in your message."
-
end
-
-
1
it 'should return site name is required when sender do not include name' do
-
1
@node = @parser.parse("dyrm a lat=12.11,lng=75.11").command
-
1
@node.sender = @user
-
1
expect(@visitor.visit_add_command(@node)).to eq(ExecVisitor::MSG[:name_is_required])
-
end
-
-
1
it 'should return key-value properties' do
-
1
@node = @parser.parse("dyrm a name=abc,doctors=5").command
-
1
expect(@visitor.node_to_properties(@node.property_list)).to eq [{:code=>"name", :value=>"abc"},{:code=>"doctors", :value=>"5"}]
-
end
-
-
1
it 'should return site properties with id and value' do
-
1
@node = @parser.parse("dyrm a name=abc,doctors=5,ambulances=10").command
-
1
expect(@visitor.node_to_site_properties(@visitor.node_to_properties(@node.property_list),@collection.id)).to eq({@f2.id.to_s=>"5", @f1.id.to_s=>"10"})
-
end
-
-
1
it 'should return a key-value site' do
-
1
@node = @parser.parse("dyrm a name=abc,lat=12.11,lng=75.11,doctors=5,ambulances=10").command
-
1
expect(@visitor.node_to_site(@visitor.node_to_properties(@node.property_list))).to eq({"name" => "abc", "lat" => "12.11", "lng" => "75.11"})
-
end
-
-
end
-
1
require 'spec_helper'
-
1
require File.expand_path(File.join(File.dirname(__FILE__), 'treetop_helper'))
-
-
1
require 'spec_helper'
-
1
require File.expand_path(File.join(File.dirname(__FILE__), 'treetop_helper'))
-
-
# parse valid query command
-
1
describe QueryCommandNode, "when parse valid query command" do
-
1
include PropertyAssertionHelper
-
1
before(:all) do
-
1
@parser = CommandParser.new
-
end
-
-
1
before(:each) do
-
4
@node = @parser.parse('dyrm q 1 beds>=8').command
-
end
-
-
1
it "should collection_id equal to 1" do
-
1
expect(@node.collection_id.value).to eq(1)
-
end
-
-
1
it "should condition name equal to 'beds'" do
-
1
@node.conditional_expression.name.text_value == 'beds'
-
end
-
-
1
it "should condition operator equal to '>='" do
-
1
@node.conditional_expression.operator.text_value == '>='
-
end
-
-
1
it "should condition value equal to 8" do
-
1
@node.conditional_expression.value.value == 8
-
end
-
end
-
-
# parse valid update command
-
1
describe UpdateCommandNode, "when parse valid update command" do
-
1
include PropertyAssertionHelper
-
1
before(:all) do
-
1
@parser = CommandParser.new
-
end
-
-
1
before(:each) do
-
4
@node = @parser.parse('dyrm u AA382 beds=5').command
-
end
-
-
1
it "should be UpdateCommandNode" do
-
1
@node.kind_of?(UpdateCommandNode) == true
-
end
-
-
1
it "should resource_id equal to AA382" do
-
1
expect(@node.resource_id.text_value).to eq('AA382')
-
end
-
-
1
it "should property_list have one property" do
-
1
@node.property_list.terminal? == true
-
end
-
-
1
it "should property name equal to 'beds' and value equal to 5" do
-
1
assert_property 'beds', 5, @node.property_list
-
end
-
end
-
-
# parse update command with more properties
-
1
describe UpdateCommandNode, "when parse valid update command with more properties" do
-
1
include PropertyAssertionHelper
-
1
before(:all) do
-
1
@parser = CommandParser.new
-
end
-
-
1
before(:each) do
-
5
@node = @parser.parse('dyrm u AA382 beds=5, doctors=2, vaccine=20').command
-
end
-
-
1
it "should be QueryCommandNode" do
-
1
@node.kind_of?(QueryCommandNode) == true
-
end
-
-
1
it "should resource_id equal to AA382" do
-
1
expect(@node.resource_id.text_value).to eq('AA382')
-
end
-
-
1
it "should the first property name equal to 'beds' and value equal to 5" do
-
1
assert_property 'beds', 5, @node.property_list
-
end
-
-
1
it "should the second property name equal to 'doctors' and value equal to 2" do
-
1
assert_property 'doctors', 2, @node.property_list.next
-
end
-
-
1
it "should the third property name equal to 'vaccine' and value equal to 20" do
-
1
assert_property 'vaccine', 20, @node.property_list.next.next
-
end
-
end
-
-
# parse invalid command
-
1
describe "when parse invalid command" do
-
1
before(:all) do
-
1
@parser = CommandParser.new
-
end
-
-
1
it "could not parse number as command node" do
-
1
node = @parser.parse('99999')
-
1
node.nil? == true
-
end
-
-
1
it "could not parse space as command node" do
-
1
node = @parser.parse(' ')
-
1
node.nil? == true
-
end
-
-
1
it "could not parse single word as command node" do
-
1
node = @parser.parse('Hello')
-
1
node.nil? == true
-
end
-
-
1
it "could not parse normal paragraph as command node" do
-
1
node = @parser.parse('Hello world ruby.')
-
1
node.nil? == true
-
end
-
-
1
it "could not parse conditional_expression as command node" do
-
1
node = @parser.parse('beds>=5')
-
1
node.nil? == true
-
end
-
-
1
it "could not parse assignment_expression as command node" do
-
1
node = @parser.parse('beds=5')
-
1
node.nil? == true
-
end
-
-
1
it "could not parse property_list as command node" do
-
1
node = @parser.parse('foo=1, bar=2')
-
1
node.nil? == true
-
end
-
end
-
1
require 'treetop_dependencies'
-
## To pre-compile grammar file in test
-
#Treetop.load File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'treetop', 'command'))
-
-
1
module PropertyAssertionHelper
-
1
def assert_property(name, value, node)
-
4
property = defined?(node.assignment_expression)? node.assignment_expression : node
-
4
property.name.text_value == name
-
4
property.value.value == value
-
end
-
end
-
-
1
require "spec_helper"
-
-
1
describe SendMailer do
-
4
let!(:users) { [User.make, User.make]}
-
4
let!(:message) {"testing"}
-
4
let!(:mail) { SendMailer.notify_email([users[0].email, users[1].email], message, "email from resourcemap") }
-
1
it "has email in queue" do
-
1
mail.deliver
-
1
expect(ActionMailer::Base.deliveries.empty?).not_to be_truthy
-
end
-
1
it "send to correct email" do
-
1
mail.deliver
-
1
expect(mail.to).to eq(users.map(&:email))
-
end
-
1
it "send a correct email" do
-
1
mail.deliver
-
1
expect(mail.body).to eq(message)
-
end
-
-
end
-
1
require 'spec_helper'
-
1
require "cancan/matchers"
-
-
1
describe Ability do
-
-
1
describe "Collection Abilities" do
-
25
let!(:admin) { User.make }
-
25
let!(:guest) { User.make is_guest: true}
-
25
let!(:user) { User.make }
-
25
let!(:member) { User.make }
-
25
let!(:collection) { admin.create_collection Collection.make }
-
25
let!(:membership) { collection.memberships.create! :user_id => member.id, admin: false }
-
-
25
let!(:admin_ability) { Ability.new(admin)}
-
25
let!(:member_ability) { Ability.new(member)}
-
25
let!(:user_ability) { Ability.new(user)}
-
25
let!(:guest_ability) { Ability.new(guest)}
-
-
-
1
describe "Destroy collection" do
-
2
it { expect(admin_ability).to be_able_to(:destroy, collection) }
-
2
it { expect(member_ability).not_to be_able_to(:destroy, collection) }
-
2
it { expect(user_ability).not_to be_able_to(:destroy, collection) }
-
2
it { expect(guest_ability).not_to be_able_to(:destroy, collection) }
-
end
-
-
1
describe "Create snapshot" do
-
2
it { expect(admin_ability).to be_able_to(:create_snapshot, collection) }
-
2
it { expect(member_ability).not_to be_able_to(:create_snapshot, collection) }
-
2
it { expect(user_ability).not_to be_able_to(:create_snapshot, collection) }
-
2
it { expect(guest_ability).not_to be_able_to(:create_snapshot, collection) }
-
end
-
-
1
describe "Update collection" do
-
2
it { expect(admin_ability).to be_able_to(:update, collection) }
-
2
it { expect(member_ability).not_to be_able_to(:upate, collection) }
-
2
it { expect(user_ability).not_to be_able_to(:update, collection) }
-
2
it { expect(guest_ability).not_to be_able_to(:update, collection) }
-
end
-
-
1
describe "Create collection" do
-
2
it { expect(guest_ability).not_to be_able_to(:create, Collection) }
-
2
it { expect(user_ability).to be_able_to(:create, Collection) }
-
end
-
-
1
describe "Public Collection Abilities" do
-
3
let!(:public_collection) { admin.create_collection Collection.make public: true}
-
-
2
it { expect(user_ability).not_to be_able_to(:read, collection) }
-
2
it { expect(user_ability).not_to be_able_to(:update, collection) }
-
-
end
-
-
1
describe "Manage snapshots" do
-
-
2
it { expect(admin_ability).to be_able_to(:create, (Snapshot.make collection: collection)) }
-
2
it { expect(member_ability).not_to be_able_to(:create, (Snapshot.make collection: collection)) }
-
2
it { expect(user_ability).not_to be_able_to(:create, (Snapshot.make collection: collection)) }
-
2
it { expect(guest_ability).not_to be_able_to(:create, (Snapshot.make collection: collection)) }
-
end
-
-
1
describe "Members" do
-
2
it { expect(admin_ability).to be_able_to(:members, collection) }
-
2
it { expect(member_ability).not_to be_able_to(:members, collection) }
-
2
it { expect(user_ability).not_to be_able_to(:members, collection) }
-
2
it { expect(guest_ability).not_to be_able_to(:members, collection) }
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Activity do
-
23
let!(:user) { User.make }
-
23
let!(:collection) { user.create_collection Collection.make_unsaved }
-
-
1
it "creates one when collection is created" do
-
1
assert_activity 'collection', 'created',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'data' => {'name' => collection.name},
-
'description' => "Collection '#{collection.name}' was created"
-
end
-
-
1
it "creates one when layer is created" do
-
1
Activity.delete_all
-
-
1
layer = collection.layers.make user: user, fields_attributes: [{kind: 'text', code: 'foo', name: 'Foo', ord: 1}]
-
-
1
assert_activity 'layer', 'created',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => layer.name, 'fields' => [{'id' => layer.fields.first.id, 'kind' => 'text', 'code' => 'foo', 'name' => 'Foo'}]},
-
'description' => "Layer '#{layer.name}' was created with fields: Foo (foo)"
-
end
-
-
1
context "layer changed" do
-
1
it "creates one when layer's name changes" do
-
1
layer = collection.layers.make user: user, name: 'Layer1', fields_attributes: [{kind: 'text', code: 'foo', name: 'Foo', ord: 1}]
-
-
1
Activity.delete_all
-
-
1
layer.name = 'Layer2'
-
1
layer.save!
-
-
1
assert_activity 'layer', 'changed',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => 'Layer1', 'changes' => {'name' => ['Layer1', 'Layer2']}},
-
'description' => "Layer 'Layer1' was renamed to '#{layer.name}'"
-
end
-
-
1
it "creates one when layer's field is added" do
-
1
layer = collection.layers.make user: user, name: 'Layer1', fields_attributes: [{kind: 'text', code: 'one', name: 'One', ord: 1}]
-
-
1
Activity.delete_all
-
-
1
layer.update_attributes! fields_attributes: [{kind: 'text', code: 'two', name: 'Two', ord: 2}]
-
-
1
field = layer.fields.last
-
-
1
assert_activity 'layer', 'changed',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => 'Layer1', 'changes' => {'added' => [{'id' => field.id, 'code' => field.code, 'name' => field.name, 'kind' => field.kind}]}},
-
'description' => "Layer 'Layer1' changed: text field 'Two' (two) was added"
-
end
-
-
1
it "creates one when layer's field's code changes" do
-
1
layer = collection.layers.make user: user, name: 'Layer1', fields_attributes: [{kind: 'text', code: 'one', name: 'One', ord: 1}]
-
-
1
Activity.delete_all
-
-
1
field = layer.fields.last
-
-
1
layer.update_attributes! fields_attributes: [{id: field.id, code: 'one1', name: 'One', ord: 1}]
-
-
1
assert_activity 'layer', 'changed',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => 'Layer1', 'changes' => {'changed' => [{'id' => field.id, 'code' => ['one', 'one1'], 'name' => 'One', 'kind' => 'text'}]}},
-
'description' => "Layer 'Layer1' changed: text field 'One' (one) code changed to 'one1'"
-
end
-
-
1
it "creates one when layer's field's name changes" do
-
1
layer = collection.layers.make user: user, name: 'Layer1', fields_attributes: [{kind: 'text', code: 'one', name: 'One', ord: 1}]
-
-
1
Activity.delete_all
-
-
1
field = layer.fields.last
-
-
1
layer.update_attributes! fields_attributes: [{id: field.id, code: 'one', name: 'One1', ord: 1}]
-
-
1
assert_activity 'layer', 'changed',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => 'Layer1', 'changes' => {'changed' => [{'id' => field.id, 'code' => 'one', 'name' => ['One', 'One1'], 'kind' => 'text'}]}},
-
'description' => "Layer 'Layer1' changed: text field 'One' (one) name changed to 'One1'"
-
end
-
-
1
it "creates one when layer's field's options changes" do
-
1
layer = collection.layers.make user: user, name: 'Layer1', fields_attributes: [{kind: 'select_one', code: 'one', name: 'One', config: {'options' => [{'code' => '1', 'label' => 'One'}]}, ord: 1}]
-
-
1
Activity.delete_all
-
-
1
field = layer.fields.last
-
-
1
begin
-
1
layer.update_attributes! fields_attributes: [{id: field.id, code: 'one', name: 'One', kind: 'select_one', config: {'options' => [{'code' => '2', 'label' => 'Two'}]}, ord: 1}]
-
rescue Exception => ex
-
puts ex.backtrace
-
end
-
-
1
assert_activity 'layer', 'changed',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => 'Layer1', 'changes' => {'changed' => [{'id' => field.id, 'code' => 'one', 'name' => 'One', 'kind' => 'select_one', 'config' => [{'options' => [{'code' => '1', 'label' => 'One'}]}, {'options' => [{'code' => '2', 'label' => 'Two'}]}]}]}},
-
'description' => %(Layer 'Layer1' changed: select_one field 'One' (one) options changed from ["One (1)"] to ["Two (2)"])
-
end
-
-
1
it "creates one when layer's field is removed" do
-
1
layer = collection.layers.make user: user, name: 'Layer1', fields_attributes: [{kind: 'text', code: 'one', name: 'One', ord: 1}, {kind: 'text', code: 'two', name: 'Two', ord: 2}]
-
-
1
Activity.delete_all
-
-
1
field = layer.fields.last
-
-
1
layer.update_attributes! fields_attributes: [{id: field.id, _destroy: true}]
-
-
1
assert_activity 'layer', 'changed',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => 'Layer1', 'changes' => {'deleted' => [{'id' => field.id, 'code' => 'two', 'name' => 'Two', 'kind' => 'text'}]}},
-
'description' => "Layer 'Layer1' changed: text field 'Two' (two) was deleted"
-
end
-
end
-
-
1
it "creates one when layer is destroyed" do
-
1
layer = collection.layers.make user: user, fields_attributes: [{kind: 'text', code: 'foo', name: 'Foo', ord: 1}]
-
-
1
Activity.delete_all
-
-
1
layer.destroy
-
-
1
assert_activity 'layer', 'deleted',
-
'collection_id' => collection.id,
-
'layer_id' => layer.id,
-
'user_id' => user.id,
-
'data' => {'name' => layer.name},
-
'description' => "Layer '#{layer.name}' was deleted"
-
end
-
-
1
it "creates one after creating a site" do
-
1
layer = collection.layers.make user: user, fields_attributes: [{kind: 'text', code: 'beds', name: 'Beds', ord: 1}]
-
1
field = layer.fields.first
-
-
1
Activity.delete_all
-
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {field.es_code => 20}, user: user
-
-
1
assert_activity 'site', 'created',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'lat' => site.lat, 'lng' => site.lng, 'properties' => site.properties},
-
'description' => "Site '#{site.name}' was created"
-
end
-
-
1
it "creates one after importing a csv" do
-
1
Activity.delete_all
-
-
1
collection.import_csv user, %(
-
resmap-id, name, lat, lng
-
1, Site 1, 30, 40
-
).strip
-
-
1
assert_activity 'collection', 'csv_imported',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'data' => {'sites' => 1},
-
'description' => "Import CSV: 1 site were imported"
-
end
-
-
1
context "site changed" do
-
10
let!(:layer) { collection.layers.make user: user, fields_attributes: [{kind: 'numeric', code: 'beds', name: 'Beds', ord: 1}, {kind: 'numeric', code: 'tables', name: 'Tables', ord: 2}, {kind: 'text', code: 'text', name: 'Text', ord: 3}] }
-
10
let(:beds) { layer.fields.first }
-
1
let(:tables) { layer.fields.second }
-
2
let(:text) { layer.fields.third }
-
-
1
it "creates one after changing one site's name" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.name = 'Bar'
-
1
site.save!
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => 'Foo', 'changes' => {'name' => ['Foo', 'Bar']}, 'lat' => 10.0, 'lng' => 20.0, 'properties' => {beds.es_code => 20}},
-
'description' => "Site 'Foo' was renamed to 'Bar'"
-
end
-
-
1
it "creates one after changing one site's location" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.lat = 15.0
-
1
site.save!
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'changes' => {'lat' => [10.0, 15.0], 'lng' => [20.0, 20.0]}, 'lat' => 15.0, 'lng' => 20.0, 'properties' => {beds.es_code => 20}},
-
'description' => "Site '#{site.name}' changed: location changed from '(10.0, 20.0)' to '(15.0, 20.0)'"
-
end
-
-
1
it "creates one after adding location in site without location" do
-
1
site = collection.sites.create! name: 'Foo', properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.lat = 15.0
-
1
site.lng = 20.0
-
-
1
site.save!
-
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'changes' => {'lat' => [ nil, 15.0], 'lng' => [nil, 20.0]}, 'lat' => 15.0, 'lng' => 20.0, 'properties' => {beds.es_code => 20}},
-
'description' => "Site '#{site.name}' changed: location changed from '(Nothing)' to '(15.0, 20.0)'"
-
end
-
-
1
it "creates one after removing location in site with location" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.lat = nil
-
1
site.lng = nil
-
-
1
site.save!
-
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'changes' => {'lat' => [10.0, nil], 'lng' => [20.0, nil]}, 'lat' => nil, 'lng' => nil, 'properties' => {beds.es_code => 20}},
-
'description' => "Site '#{site.name}' changed: location changed from '(10.0, 20.0)' to '(Nothing)'"
-
end
-
-
1
it "creates one after adding one site's property" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {}, user: user
-
-
1
Activity.delete_all
-
-
1
site.properties_will_change!
-
1
site.properties[beds.es_code] = 30
-
1
site.save!
-
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'changes' => {'properties' => [{}, {beds.es_code => 30}]}, 'lat' => 10.0, 'lng' => 20.0, 'properties' => {beds.es_code => 30}},
-
'description' => "Site '#{site.name}' changed: 'beds' changed from '(Nothing)' to '30'"
-
end
-
-
1
it "creates one after changing one site's property" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.properties_will_change!
-
1
site.properties[beds.es_code] = 30
-
1
site.save!
-
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'changes' => {'properties' => [{beds.es_code => 20}, {beds.es_code => 30}]}, 'lat' => 10.0, 'lng' => 20.0, 'properties' => {beds.es_code => 30}},
-
'description' => "Site '#{site.name}' changed: 'beds' changed from '20' to '30'"
-
end
-
-
1
it "creates one after changing many site's properties" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {beds.es_code => 20, text.es_code => 'foo'}, user: user
-
-
1
Activity.delete_all
-
-
1
site.properties_will_change!
-
1
site.properties[beds.es_code] = 30
-
1
site.properties[text.es_code] = 'bar'
-
1
site.save!
-
-
1
assert_activity 'site', 'changed',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name, 'changes' => {'properties' => [{beds.es_code => 20, text.es_code => 'foo'}, {beds.es_code => 30, text.es_code => 'bar'}]}, 'lat' => 10.0, 'lng' => 20.0, 'properties' => {beds.es_code => 30, text.es_code => 'bar'}},
-
'description' => "Site '#{site.name}' changed: 'beds' changed from '20' to '30', 'text' changed from 'foo' to 'bar'"
-
end
-
-
1
it "doesn't create one after siglaning properties will change but they didn't change" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.properties_will_change!
-
1
site.save!
-
-
1
expect(Activity.count).to eq(0)
-
end
-
-
1
it "doesn't create one if lat/lng updated but not changed" do
-
1
site = collection.sites.create! name: 'Foo', lat: "-1.9537", lng: "30.10309", properties: {beds.es_code => 20}, user: user
-
-
1
Activity.delete_all
-
-
1
site.lat = "-1.9537"
-
1
site.lng = "30.103090000000066"
-
1
site.save!
-
-
1
expect(Activity.count).to eq(0)
-
end
-
end
-
-
1
it "creates one after destroying a site" do
-
1
site = collection.sites.create! name: 'Foo', lat: 10.0, lng: 20.0, location_mode: :manual, user: user
-
-
1
Activity.delete_all
-
-
1
site.destroy
-
-
1
assert_activity 'site', 'deleted',
-
'collection_id' => collection.id,
-
'user_id' => user.id,
-
'site_id' => site.id,
-
'data' => {'name' => site.name},
-
'description' => "Site '#{site.name}' was deleted"
-
end
-
-
1
def assert_activity(item_type, action, options = {})
-
19
activities = Activity.all
-
19
expect(activities.length).to eq(1)
-
-
19
expect(activities[0].item_type).to eq(item_type)
-
19
expect(activities[0].action).to eq(action)
-
19
options.each do |key, value|
-
93
expect(activities[0].send(key)).to eq(value)
-
end
-
end
-
-
1
describe "migrate data" do
-
1
before(:each) do
-
1
TSite = Struct.new(:id, :name, :lat, :lng, :properties)
-
1
TActivity = Struct.new :user, :site, :data, :item_type, :action, :created_at, :save
-
1
@user = User.make
-
1
@site1 = TSite.new(10, "Kampong Pou" , 10.30, 15.30 , "120" => "channa@info", "145" => "10" , "290" => "20", "310" => "097555")
-
-
1
@field = {
-
"120" => "Email",
-
"145" => "No Bed",
-
"290" => "No Doctor",
-
"310" => "Phone"
-
}
-
-
1
now = Date.current
-
-
1
activity4 = TActivity.new @user, @site1, {
-
"name"=>"Kampong Pou",
-
"changes"=>{"properties"=>[
-
{"120"=> "tola@gmail", "145"=> "200" },
-
{"120"=> "channa@info", "145"=> "10" }
-
]} }, "site", "changed", now-1.day
-
-
1
activity3 = TActivity.new @user,@site1, {
-
"name"=>"Kampong Pou",
-
"changes"=>{"properties"=>[
-
{"120"=> "vicheka@gmail", "290" => "90" },
-
{"120"=> "tola@gmail", "290" => "20" }
-
]} }, "site", "changed", now-2.day
-
-
-
1
activity2 = TActivity.new @user, @site1,{
-
"name"=>"Kampong Pou",
-
"changes"=>{"properties"=>[
-
{"120"=> "theary@gmail", "290" => "100" },
-
{"120"=> "vicheka@gmail", "290" => "90" }
-
]} }, "site", "changed", now-3.day
-
-
1
activity1 = TActivity.new @user, @site1, {
-
"name"=>"Kampong Pou",
-
"changes"=>{
-
"lat"=>[15.90 , 10.30],
-
"lng"=>[50.30 , 15.30]}
-
},"site", "changed", now- 4.day
-
-
1
activity0 = TActivity.new @user, @site1, {
-
"name"=>"Champa",
-
"changes"=>{
-
"name" => ["Champa", "Kampong Pou"]
-
}
-
},"site", "changed", now- 5.day
-
-
1
@activities = [ activity4, activity3, activity2, activity1 , activity0]
-
-
end
-
-
1
it "should migrate activities log for site to add incremental properties something" do
-
1
activities = Activity.migrate_activities_of_site(@activities, @site1)
-
-
1
expect(activities.size).to eq 5
-
-
1
expect(activities[0].data["properties"]).to eq({"120"=>"channa@info", "145"=>"10", "290"=>"20", "310"=>"097555"})
-
1
expect(activities[0].data["lat"]).to eq 10.30
-
1
expect(activities[0].data["lng"]).to eq 15.30
-
-
-
1
expect(activities[1].data["properties"]).to eq({"120"=>"tola@gmail", "145"=>"200", "290"=>"20", "310"=>"097555"})
-
1
expect(activities[1].data["lat"]).to eq 10.30
-
1
expect(activities[1].data["lng"]).to eq 15.30
-
-
1
expect(activities[2].data["properties"]).to eq({"120"=>"vicheka@gmail", "145"=>"200", "290"=>"90", "310"=>"097555"})
-
1
expect(activities[2].data["lat"]).to eq 10.30
-
1
expect(activities[2].data["lng"]).to eq 15.30
-
-
-
1
expect(activities[3].data["properties"]).to eq({"120"=>"theary@gmail", "145"=>"200", "290"=>"100", "310"=>"097555"})
-
1
expect(activities[3].data["lat"]).to eq 10.30
-
1
expect(activities[3].data["lng"]).to eq 15.30
-
-
1
expect(activities[4].data["properties"]).to eq({"120"=>"theary@gmail", "145"=>"200", "290"=>"100", "310"=>"097555"})
-
1
expect(activities[4].data["lat"]).to eq 15.90
-
1
expect(activities[4].data["lng"]).to eq 50.30
-
1
expect(activities[4].data["name"]).to eq "Champa"
-
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Clusterer do
-
12
let(:clusterer) { Clusterer.new 1 }
-
4
let(:collection) { Collection.make }
-
1
it "leaves single site alone" do
-
1
clusterer.add id: 1, name: 'foo',lat: 30, lng: 40, collection_id: 12
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to eq([{id: 1, name: 'foo', lat: 30, lng: 40, collection_id: 12, highlighted: false}])
-
1
expect(clusters[:clusters]).to be_nil
-
end
-
-
1
it "puts two sites in a cluster" do
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([{:alert => false, :status => true, :icon => "", :color => "", :id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 0, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted=>false}])
-
end
-
-
1
it "puts four sites in two different clusters" do
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31
-
1
clusterer.add :id => 3, :lat => 65, :lng => 120
-
1
clusterer.add :id => 4, :lat => 66, :lng => 121
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 0, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted=>false, :alert => false, :status => true, :icon => "", :color => "" },
-
{:id => "1:3:4", :lat => 65.5, :lng => 120.5, :count => 2, :alert_count => 0, :min_lat => 65, :max_lat => 66, :min_lng => 120, :max_lng => 121, :highlighted=>false, :alert => false, :status => true, :icon => "", :color => "" }
-
])
-
end
-
-
1
it "puts four sites in two different clusters with two sites alert" do
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :alert => "true", :collection_id => collection.id
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31
-
1
clusterer.add :id => 3, :lat => 65, :lng => 120, :alert => "true", :collection_id => collection.id
-
1
clusterer.add :id => 4, :lat => 66, :lng => 121
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 1, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted=>false, :alert => true, :status => false, :icon => "default", :color =>""},
-
{:id => "1:3:4", :lat => 65.5, :lng => 120.5, :count => 2, :alert_count => 1, :min_lat => 65, :max_lat => 66, :min_lng => 120, :max_lng => 121, :highlighted=>false, :alert => true, :status => false, :icon => "default", :color =>""}
-
])
-
end
-
-
1
it "cluster is highlighted when it contains sites under certain hierarchy" do
-
1
clusterer.highlight(code: "beds", selected: ["2"])
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :property => ["2"]
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31, :property => ["1"]
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 0, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted => true, :alert => false, :status => true, :icon => "", :color => "" }
-
])
-
end
-
-
1
it "should not highlight cluster when it not contains sites under certain hierarchy" do
-
1
clusterer.highlight(code: "beds", selected: ["2"])
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :property => ["7"]
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31, :property => ["1"]
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 0, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted => false, :alert => false, :status => true, :icon => "", :color => "" }
-
])
-
end
-
-
1
it "should highlight cluster when property is multi valued" do
-
1
clusterer.highlight(code: "beds", selected: ["2"])
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :property => ["7", "2"]
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31, :property => ["1", "4", "3"]
-
1
clusterer.add :id => 3, :lat => 34, :lng => 0, :property => ["1", "2", "3"]
-
-
1
clusters = clusterer.clusters
-
-
1
expect(clusters[:sites]).to eq([{:id => 3, :lat => 34, :lng => 0, :highlighted => true}])
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 0, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted => true, :alert => false, :status => true, :icon => "", :color => "" }
-
])
-
end
-
-
1
it "should select more than one value (for hiearchies >1 level)" do
-
1
clusterer.highlight(code: "beds", selected: ["2", "3"])
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :property => ["7", "2"]
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31, :property => ["1", "4", "3"]
-
1
clusterer.add :id => 3, :lat => 34, :lng => 0, :property => ["1", "2", "3"]
-
-
1
clusters = clusterer.clusters
-
-
1
expect(clusters[:sites]).to eq([{:id => 3, :lat => 34, :lng => 0, :highlighted => true}])
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 0, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted => true, :alert => false, :status => true, :icon => "", :color => "" }
-
])
-
end
-
-
1
it "should add ghost lat and lng to each site for site in identical location if clustering is not enabled" do
-
1
clusterer.send(:initialize, 21)
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30
-
1
clusterer.add :id => 2, :lat => 20, :lng => 30
-
1
clusterer.add :id => 3, :lat => 20, :lng => 30
-
1
clusterer.add :id => 4, :lat => 20, :lng => 30
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to eq(
-
[{:id=>1, :lat=>20, :lng=>30, :ghost_radius => 2*Math::PI/4 * 0 },
-
{:id=>2, :lat=>20, :lng=>30, :ghost_radius => 2*Math::PI/4 * 1 },
-
{:id=>3, :lat=>20, :lng=>30, :ghost_radius => 2*Math::PI/4 * 2 },
-
{:id=>4, :lat=>20, :lng=>30, :ghost_radius => 2*Math::PI/4 * 3 }
-
])
-
1
expect(clusters[:clusters]).to be_nil
-
1
expect(clusters[:original_ghost]).to eq([{:lat => 20, :lng => 30}])
-
-
end
-
-
1
it 'should set status = false when two sites in difference collection in the same cluster' do
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :alert => "true", :collection_id => collection.id
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31, :collection_id => 1
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 1, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted=>false, :alert => true, :status => false, :icon => "default", :color => ""}
-
])
-
end
-
-
1
it 'should return status = true, icon = cycling and color = nil when two sites in difference collection in the same cluster' do
-
1
clusterer.add :id => 1, :lat => 20, :lng => 30, :alert => "true", :collection_id => collection.id, :icon => 'cycling'
-
1
clusterer.add :id => 2, :lat => 21, :lng => 31, :collection_id => collection.id , :icon => 'cycling'
-
-
1
clusters = clusterer.clusters
-
1
expect(clusters[:sites]).to be_nil
-
1
expect(clusters[:clusters]).to eq([
-
{:id => "1:2:3", :lat => 20.5, :lng => 30.5, :count => 2, :alert_count => 1, :min_lat => 20, :max_lat => 21, :min_lng => 30, :max_lng => 31, :highlighted=>false, :alert => true, :status => true, :icon => "cycling", :color => nil}
-
])
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Collection::CsvConcern do
-
17
let(:user) { User.make }
-
17
let(:collection) { user.create_collection Collection.make }
-
17
let!(:layer) { collection.layers.make }
-
-
1
it "imports csv" do
-
1
collection.import_csv user, %(
-
resmap-id, name, lat, lng
-
1, Site 1, 10, 20
-
2, Site 2, 30, 40
-
).strip
-
-
1
collection.reload
-
1
roots = collection.sites.reload
-
1
expect(roots.length).to eq(2)
-
-
1
expect(roots[0].name).to eq('Site 1')
-
1
expect(roots[0].lat.to_f).to eq(10.0)
-
1
expect(roots[0].lng.to_f).to eq(20.0)
-
-
1
expect(roots[1].name).to eq('Site 2')
-
1
expect(roots[1].lat.to_f).to eq(30.0)
-
1
expect(roots[1].lng.to_f).to eq(40.0)
-
end
-
-
1
it "should print date as MM/DD/YYYY" do
-
1
date = layer.date_fields.make :code => 'date'
-
1
site = collection.sites.make :properties => {date.es_code => '1985-10-19T00:00:00Z'}
-
-
1
csv = CSV.parse collection.to_csv(collection.new_search(:current_user_id => user.id).unlimited.api_results, user)
-
-
1
expect(csv[1][4]).to eq('10/19/1985')
-
end
-
-
1
it "should download hiearchy value as Name" do
-
1
config_hierarchy = [{ id: '60', name: 'Dad', sub: [{id: '100', name: 'Son'}, {id: '101', name: 'Bro'}]}]
-
1
hierarchy_field = layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access
-
-
1
site = collection.sites.make :properties => {hierarchy_field.es_code => '100'}
-
-
1
csv = CSV.parse collection.to_csv(collection.new_search(:current_user_id => user.id).unlimited.api_results, user)
-
1
expect(csv[1][4]).to eq('Son')
-
end
-
-
1
describe "generate sample csv" do
-
-
1
it "should include only visible fields for the user" do
-
1
user2 = User.make
-
-
1
layer_visible = collection.layers.make
-
1
layer_invisible = collection.layers.make
-
1
layer_writable = collection.layers.make
-
-
1
date_visible = layer_visible.date_fields.make :code => 'date_visible'
-
1
date_invisible = layer_invisible.date_fields.make :code => 'date_invisible'
-
1
date_writable = layer_writable.date_fields.make :code => 'date_writable'
-
-
1
membership = collection.memberships.make :user => user2
-
1
membership.admin = false
-
1
membership.set_layer_access :verb => :read, :access => true, :layer_id => layer_visible.id
-
1
membership.set_layer_access :verb => :write, :access => false, :layer_id => layer_visible.id
-
1
membership.set_layer_access :verb => :read, :access => false, :layer_id => layer_invisible.id
-
1
membership.set_layer_access :verb => :write, :access => false, :layer_id => layer_invisible.id
-
1
membership.set_layer_access :verb => :read, :access => true, :layer_id => layer_writable.id
-
1
membership.set_layer_access :verb => :write, :access => true, :layer_id => layer_writable.id
-
1
membership.save!
-
-
1
csv = CSV.parse(collection.sample_csv user2)
-
-
1
expect(csv[0]).to include('date_writable')
-
1
expect(csv[0]).not_to include('date_visible')
-
1
expect(csv[0]).not_to include('date_invisible')
-
1
expect(csv[1].length).to be(4)
-
end
-
end
-
-
1
describe "decode hierarchy csv test" do
-
-
1
it "gets parents right" do
-
1
json = collection.decode_hierarchy_csv %(
-
ID, ParentID, ItemName
-
1,,Dispensary
-
2,,Health Centre
-
101,1,Lab Dispensary
-
102,1,Clinical Dispensary
-
201,2,Health Centre Type 1
-
202,2,Health Centre Type 2
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Dispensary', sub: [{order: 3, id: '101', name: 'Lab Dispensary'}, {order: 4, id: '102', name: 'Clinical Dispensary'}]},
-
{order: 2, id: '2', name: 'Health Centre', sub: [{order: 5, id: '201', name: 'Health Centre Type 1'}, {order: 6, id: '202', name: 'Health Centre Type 2'}]},
-
])
-
end
-
-
-
1
it "decodes hierarchy csv" do
-
1
json = collection.decode_hierarchy_csv %(
-
ID, ParentID, ItemName
-
1,,Site 1
-
2,,Site 2
-
3,,Site 3
-
4,1,Site 1.1
-
5,1,Site 1.2
-
6,1,Site 1.3
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1', sub: [{order: 4, id: '4', name: 'Site 1.1'}, {order: 5, id: '5', name: 'Site 1.2'}, {order: 6, id: '6', name: 'Site 1.3'}]},
-
{order: 2, id: '2', name: 'Site 2'},
-
{order: 3, id: '3', name: 'Site 3'}
-
])
-
end
-
-
1
it "without header" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 2
-
3,,Site 3
-
4,1,Site 1.1
-
5,1,Site 1.2
-
6,1,Site 1.3
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1', sub: [{order: 4, id: '4', name: 'Site 1.1'}, {order: 5, id: '5', name: 'Site 1.2'}, {order: 6, id: '6', name: 'Site 1.3'}]},
-
{order: 2, id: '2', name: 'Site 2'},
-
{order: 3, id: '3', name: 'Site 3'}
-
])
-
end
-
-
1
it "gets an error if has >3 columns in a row" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 2
-
3,,Site 3,
-
4,1,Site 1.1
-
5,1,Site 1.2
-
6,1,Site 1.3
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1', sub: [{order: 4, id: '4', name: 'Site 1.1'}, {order: 5, id: '5', name: 'Site 1.2'}, {order: 6, id: '6', name: 'Site 1.3'}]},
-
{order: 2, id: '2', name: 'Site 2'},
-
{order: 3, error: 'Wrong format.', error_description: 'Invalid column number'}
-
])
-
end
-
-
1
it "gets an error if has <3 columns in a row" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 2
-
3,,Site 3
-
4,1,Site 1.1
-
5,1,Site 1.2
-
6,
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1', sub: [{order: 4, id: '4', name: 'Site 1.1'}, {order: 5, id: '5', name: 'Site 1.2'}]},
-
{order: 2, id: '2', name: 'Site 2'},
-
{order: 3, id: '3', name: 'Site 3'},
-
{order: 6, error: 'Wrong format.', error_description: 'Invalid column number'}
-
])
-
end
-
-
# works ok in the app but the test is not working
-
1
it "works ok with quotes" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 2
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1'},
-
{order: 2, id: '2', name: 'Site 2'}
-
])
-
end
-
-
1
it "gets an error if the parent does not exists" do
-
1
json = collection.decode_hierarchy_csv %(
-
ID, ParentID, ItemName
-
1,,Dispensary
-
2,,Health Centre
-
101,10,Lab Dispensary
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Dispensary', },
-
{order: 2, id: '2', name: 'Health Centre'},
-
{order: 3, error: 'Invalid parent value.', error_description: 'ParentID should match one of the Hierarchy ids'},
-
])
-
end
-
-
1
it "gets an error if there is wrong quotes (when creating file in excel without export it to csv)" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 2
-
3,,Site 3
-
"4,,Site 4
-
-
).strip
-
-
1
expect(json).to eq([
-
{error: "Illegal quoting in line 4."}
-
])
-
end
-
-
1
it ">1 column number errors" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 2,
-
3,,Site 3,
-
4,,Site 4
-
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1'},
-
{order: 2, error: 'Wrong format.', error_description: 'Invalid column number'},
-
{order: 3, error: 'Wrong format.', error_description: 'Invalid column number'},
-
{order: 4, id: '4', name: 'Site 4'}
-
-
])
-
end
-
-
1
it "hierarchy name should be unique" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 1
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1'},
-
{order: 2, error: 'Invalid name.', error_description: 'Hierarchy name should be unique'}
-
])
-
end
-
-
1
it "more than one hierarchy name repeated" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
2,,Site 1
-
3,,Site 1
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1'},
-
{order: 2, error: 'Invalid name.', error_description: 'Hierarchy name should be unique'},
-
{order: 3, error: 'Invalid name.', error_description: 'Hierarchy name should be unique'}
-
])
-
end
-
-
1
it "hiearchy id should be unique" do
-
1
json = collection.decode_hierarchy_csv %(
-
1,,Site 1
-
1,,Site 2
-
1,,Site 3
-
).strip
-
-
1
expect(json).to eq([
-
{order: 1, id: '1', name: 'Site 1'},
-
{order: 2, error: 'Invalid id.', error_description: 'Hierarchy id should be unique'},
-
{order: 3, error: 'Invalid id.', error_description: 'Hierarchy id should be unique'}
-
])
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Collection::GeomConcern do
-
6
let(:collection) { Collection.make }
-
-
1
it "calculates center from children sites" do
-
1
site1 = collection.sites.make :lat => 30, :lng => 20
-
1
site2 = collection.sites.make :lat => 40, :lng => 30
-
-
1
collection.reload
-
1
expect(collection.lat.to_f).to eq(35.0)
-
1
expect(collection.lng.to_f).to eq(25.0)
-
end
-
-
1
it "calculates center from children sites is not weighted" do
-
1
site1 = collection.sites.make :lat => 30, :lng => 20
-
1
site2 = collection.sites.make :lat => 40, :lng => 30
-
1
site3 = collection.sites.make :lat => 40, :lng => 30
-
-
1
collection.reload
-
1
expect(collection.lat.to_f).to eq(35.0)
-
1
expect(collection.lng.to_f).to eq(25.0)
-
end
-
-
1
it "calculates bounding box from children" do
-
1
site1 = collection.sites.make :lat => 30, :lng => 20
-
1
site2 = collection.sites.make :lat => 40, :lng => 30
-
1
site3 = collection.sites.make :lat => 45, :lng => 40
-
-
1
collection.reload
-
1
expect(collection.min_lat.to_f).to eq(30.0)
-
1
expect(collection.max_lat.to_f).to eq(45.0)
-
1
expect(collection.min_lng.to_f).to eq(20.0)
-
1
expect(collection.max_lng.to_f).to eq(40.0)
-
end
-
-
1
it "ignores sites without lat/lng", :focus => true do
-
1
site1 = collection.sites.make :lat => nil, :lng => nil
-
1
site2 = collection.sites.make :lat => 30, :lng => 20
-
-
1
collection.reload
-
1
expect(collection.lat.to_f).to eq(30.0)
-
1
expect(collection.lng.to_f).to eq(20.0)
-
end
-
-
1
it "calculates center from children sites after destroy" do
-
1
site1 = collection.sites.make :lat => 30, :lng => 20
-
1
site2 = collection.sites.make :lat => 40, :lng => 30
-
1
site2.destroy
-
-
1
collection.reload
-
1
expect(collection.lat.to_f).to eq(30.0)
-
1
expect(collection.lng.to_f).to eq(20.0)
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Collection::ImportLayersSchemaConcern do
-
4
let(:collection) { Collection.make }
-
4
let(:other_collection) { Collection.make }
-
4
let(:other_layer) { other_collection.layers.make name: "Adminsitrative Information", ord: 1, public: false }
-
-
4
let(:user) { User.make}
-
-
1
it 'should import json_layer without fields' do
-
1
json = [other_layer].to_json
-
1
expect(collection.layers.count).to eq(0)
-
1
sleep 2
-
1
collection.import_schema(json, user)
-
1
expect(collection.layers.count).to eq(1)
-
1
collection_new_layer = collection.layers.first
-
1
expect(collection_new_layer.name).to eq("Adminsitrative Information")
-
1
expect(collection_new_layer.ord).to eq(1)
-
1
expect(collection_new_layer.id).not_to eq(other_layer.id)
-
1
expect(collection_new_layer.collection_id).not_to eq(other_layer.collection_id)
-
1
expect(collection_new_layer.created_at).not_to eq(other_layer.created_at)
-
1
expect(collection_new_layer.updated_at).not_to eq(other_layer.updated_at)
-
1
expect(collection_new_layer.public).to eq(false)
-
end
-
-
1
it 'should import json_layer with numeric field' do
-
1
other_layer.numeric_fields.make code: 'numBeds', name: 'Number of Beds', config: { :allows_decimals => "true" }
-
1
other_field = other_layer.fields.first
-
1
json = other_collection.layers.includes(:fields).to_json(include: :fields)
-
1
sleep 2
-
1
collection.import_schema(json, user)
-
1
expect(collection.fields.count).to eq(1)
-
1
new_field = collection.fields.first
-
1
expect(new_field.code).to eq('numBeds')
-
1
expect(new_field.name).to eq('Number of Beds')
-
1
expect(new_field.kind).to eq('numeric')
-
1
expect(new_field.updated_at).not_to eq(other_field.updated_at)
-
1
expect(new_field.id).not_to eq(other_field.id)
-
1
expect(new_field.collection_id).not_to eq(other_field.collection_id)
-
1
expect(new_field.collection_id).to eq(collection.id)
-
1
expect(new_field.allow_decimals?).to eq(true)
-
end
-
-
1
it 'should import json_layer with options field' do
-
1
config_hierarchy = [{ id: '1', name: 'Dad', sub: [{id: '2', name: 'Son'}, {id: '3', name: 'Bro'}]}]
-
1
other_layer.hierarchy_fields.make :code => 'family', config: { hierarchy: config_hierarchy }.with_indifferent_access
-
1
other_field = other_layer.fields.first
-
1
json = other_collection.layers.includes(:fields).to_json(include: :fields)
-
1
collection.import_schema(json, user)
-
1
expect(collection.fields.count).to eq(1)
-
1
new_field = collection.fields.first
-
1
expect(new_field.hierarchy_options.length).to eq(3)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Collection::ShpConcern do
-
3
let(:user) { User.make time_zone: 'UTC' }
-
3
let(:collection) { user.collections.make }
-
-
1
describe "generate dbf record" do
-
3
let(:date_string) { '20140620T080000.000+0700' }
-
1
let(:data_source) {
-
2
{ 'created_at' => date_string, 'updated_at' => date_string }
-
}
-
-
1
describe "apply timezone" do
-
3
let(:record) { collection.dbf_record_for data_source }
-
-
1
before(:each) do
-
2
collection.time_zone = 'UTC'
-
end
-
-
1
it 'should format created_at' do
-
1
expect(record.data['created_at']).to eq 'Fri, 20 Jun 2014 01:00:00 +0000'
-
end
-
-
1
it 'should format updated_at' do
-
1
expect(record.data['updated_at']).to eq 'Fri, 20 Jun 2014 01:00:00 +0000'
-
end
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Collection do
-
2
it { is_expected.to validate_presence_of :name }
-
2
it { is_expected.to have_many :memberships }
-
2
it { is_expected.to have_many :users }
-
2
it { is_expected.to have_many :layers }
-
2
it { is_expected.to have_many :fields }
-
2
it { is_expected.to have_many :thresholds }
-
-
29
let!(:user) { User.make }
-
27
let!(:collection) { user.create_collection Collection.make_unsaved }
-
29
let!(:layer) { collection.layers.make user: user, fields_attributes: [{kind: 'numeric', code: 'foo', name: 'Foo', ord: 1}] }
-
29
let!(:field) { layer.fields.first }
-
-
1
context "max value" do
-
1
it "gets max value for property that exists" do
-
1
collection.sites.make :properties => {field.es_code => 10}
-
1
collection.sites.make :properties => {field.es_code => 20}, :lat => nil, :lng => nil
-
1
collection.sites.make :properties => {field.es_code => 5}
-
-
1
expect(collection.max_value_of_property(field.es_code)).to eq(20)
-
end
-
end
-
-
1
describe "thresholds test" do
-
6
let!(:site) { collection.sites.make properties: {field.es_code => 9}}
-
1
it "should return false when there is no threshold" do
-
1
expect(collection.thresholds_test(site)).to be_falsey
-
end
-
-
1
it "should return false when no threshold is hit" do
-
1
collection.thresholds.make is_all_site: true, conditions: [ field: 1, op: :gt, value: 10 ]
-
1
expect(collection.thresholds_test(site)).to be_falsey
-
end
-
-
1
it "should return true when threshold 1 is hit" do
-
1
collection.thresholds.make is_all_site: false, sites: [{"id" => site.id}], conditions: [ field: field.es_code, op: :lt, value: 10 ]
-
1
expect(collection.thresholds_test(site)).to be_truthy
-
end
-
-
1
it "should return true when threshold 2 is hit" do
-
1
collection.thresholds.make sites: [{"id" => site.id}], conditions: [ field: field.es_code, op: :gt, value: 10 ]
-
1
collection.thresholds.make sites: [{"id" => site.id}], conditions: [ field: field.es_code, op: :eq, value: 9 ]
-
1
expect(collection.thresholds_test(site)).to be_truthy
-
end
-
-
1
describe "multiple thresholds test" do
-
2
let!(:site_2) { collection.sites.make properties: {field.es_code => 25}}
-
-
1
it "should evaluate second threshold" do
-
1
collection.thresholds.make is_all_site: false, conditions: [ {field: field.es_code, op: :gt, value: 10} ], sites: [{ "id" => site.id }]
-
1
collection.thresholds.make is_all_site: false, conditions: [ {field: field.es_code, op: :gt, value: 20} ], sites: [{ "id" => site_2.id }]
-
1
expect(collection.thresholds_test(site_2)).to be_truthy
-
end
-
end
-
end
-
-
1
describe "SMS query" do
-
1
describe "Operator parser" do
-
1
it "should return operator for search class" do
-
1
expect(collection.operator_parser(">")).to eq("gt")
-
1
expect(collection.operator_parser("<")).to eq("lt")
-
1
expect(collection.operator_parser("=>")).to eq("gte")
-
1
expect(collection.operator_parser("=<")).to eq("lte")
-
1
expect(collection.operator_parser(">=")).to eq("gte")
-
1
expect(collection.operator_parser("<=")).to eq("lte")
-
end
-
end
-
end
-
-
1
describe "History" do
-
1
it "shold have user_snapshots througt snapshots" do
-
1
snp_1 = collection.snapshots.create! date: Time.now, name: 'snp1'
-
1
snp_2 = collection.snapshots.create! date: Time.now, name: 'snp2'
-
-
1
snp_1.user_snapshots.create! user: User.make
-
1
snp_2.user_snapshots.create! user: User.make
-
-
1
expect(collection.user_snapshots.count).to eq(2)
-
1
expect(collection.user_snapshots.first.snapshot.name).to eq('snp1')
-
1
expect(collection.user_snapshots.last.snapshot.name).to eq('snp2')
-
end
-
-
1
it "should obtain snapshot for user if user_snapshot exists" do
-
1
user = User.make
-
1
snp_1 = collection.snapshots.create! date: Time.now, name: 'snp1'
-
1
snp_1.user_snapshots.create! user: user
-
-
1
snp_2 = collection.snapshots.create! date: Time.now, name: 'snp2'
-
1
snp_2.user_snapshots.create! user: User.make
-
-
1
snapshot = collection.snapshot_for(user)
-
1
expect(snapshot.name).to eq('snp1')
-
end
-
-
1
it "should obtain nil snapshot_name for user if user_snapshot does not exists" do
-
1
snp_1 = collection.snapshots.create! date: Time.now, name: 'snp1'
-
1
snp_1.user_snapshots.create! user: User.make
-
-
1
user = User.make
-
1
snapshot = collection.snapshot_for(user)
-
1
expect(snapshot).to be_nil
-
end
-
-
-
end
-
-
1
describe 'gateway' do
-
3
let!(:admin_user) { User.make }
-
3
let!(:collection_1) { admin_user.create_collection Collection.make_unsaved}
-
3
let!(:channel) { Channel.make name: 'default', basic_setup: true, ticket_code: '2222', user_id: admin_user.id }
-
-
1
it 'should return user_owner of collection' do
-
1
expect(collection_1.get_user_owner).to eq admin_user
-
end
-
-
1
it 'should return gateway under user_owner' do
-
1
expect(channel.user_id).to eq admin_user.id
-
1
expect(collection_1.get_gateway_under_user_owner).to eq channel
-
end
-
end
-
-
1
describe 'es_codes_by_field_code' do
-
2
let!(:collection_a) { user.create_collection Collection.make_unsaved }
-
2
let!(:layer_a) { collection_a.layers.make user: user }
-
-
2
let!(:field_a) { layer_a.text_fields.make code: 'A', name: 'A', ord: 1 }
-
2
let!(:field_b) { layer_a.text_fields.make code: 'B', name: 'B', ord: 2 }
-
2
let!(:field_c) { layer_a.text_fields.make code: 'C', name: 'C', ord: 3 }
-
2
let!(:field_d) { layer_a.text_fields.make code: 'D', name: 'D', ord: 4 }
-
-
1
it 'returns a dict of es_codes by field_code' do
-
1
dict = collection_a.es_codes_by_field_code
-
-
1
expect(dict['A']).to eq(field_a.es_code)
-
1
expect(dict['B']).to eq(field_b.es_code)
-
1
expect(dict['C']).to eq(field_c.es_code)
-
1
expect(dict['D']).to eq(field_d.es_code)
-
end
-
end
-
-
1
describe 'site_ids_permission' do
-
2
let(:collection) { user.create_collection Collection.make_unsaved }
-
2
let(:user_2) { User.make }
-
-
1
context 'when no memberships' do
-
1
it "should have empty site ids permission" do
-
1
expect(collection.site_ids_permission(user_2)).to be_empty
-
end
-
end
-
end
-
-
1
describe 'visible_layers_for' do
-
2
let(:collection) { user.create_collection Collection.make_unsaved }
-
-
1
context 'when user is not a collection member' do
-
2
let(:user_2) { User.make }
-
-
1
it "should have no layer" do
-
1
expect(collection.visible_layers_for(user_2)).to be_empty
-
end
-
end
-
end
-
-
1
describe "#is site exist?" do
-
1
before(:each) do
-
4
site1 = collection.sites.make device_id: 'dv1', external_id: '1',properties: {}
-
4
site2 = collection.sites.make device_id: 'dv1', external_id: '2',properties: {}
-
end
-
1
it "should return true when the site is not exist yet" do
-
1
site3 = Site.new name: "Site3", collection_id: collection.id, device_id: 'dv1', external_id: '3', properties: {}
-
1
expect(collection.is_site_exist?(site3.device_id, site3.external_id)).to be_falsey
-
end
-
-
1
it "should return false when the site is already exist" do
-
1
site4 = Site.new name: "Site4", collection_id: collection.id, device_id: 'dv1', external_id: '1', properties: {}
-
1
expect(collection.is_site_exist?(site4.device_id, site4.external_id)).to be_truthy
-
end
-
1
it "should return false when the device_id is not exist yet" do
-
1
site5 = Site.new name: "Site5", collection_id: collection.id, device_id: 'dv2', external_id: '1', properties: {}
-
1
expect(collection.is_site_exist?(site5.device_id, site5.external_id)).to be_falsey
-
end
-
-
1
it "should return false without device_id" do
-
1
site6 = Site.new name: "Site6", collection_id: collection.id, properties: {}
-
1
expect(collection.is_site_exist?(site6.device_id, site6.external_id)).to be_falsey
-
end
-
end
-
-
1
describe 'telemetry' do
-
1
it 'should touch lifespan on create' do
-
1
collection = Collection.make_unsaved
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
collection.save
-
end
-
-
1
it 'should touch lifespan on update' do
-
1
collection = Collection.make
-
1
collection.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
collection.save
-
end
-
-
1
it 'should touch lifespan on destroy' do
-
1
collection = Collection.make
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
collection.destroy
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
1
require 'elastic_search/query_helper.rb'
-
-
1
describe ElasticSearch::QueryHelper do
-
4
let!(:collection) { Collection.make }
-
-
1
it 'does not append wildcard to integer queries' do
-
1
query = ElasticSearch::QueryHelper.full_text_search '34', nil, collection
-
1
expect(query.last).not_to end_with('*')
-
end
-
-
1
it 'appends wildcard to decimal queries' do
-
1
query = ElasticSearch::QueryHelper.full_text_search '34.9', nil, collection
-
1
expect(query.last).to end_with('*')
-
1
query = ElasticSearch::QueryHelper.full_text_search '-34.9', nil, collection
-
1
expect(query.last).to end_with('*')
-
end
-
-
1
it 'does not append wildcard to separate words queries' do
-
1
query = ElasticSearch::QueryHelper.full_text_search 'one two', nil, collection
-
1
expect(query.last).not_to end_with('*')
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe ElasticSearch::SitesAdapter do
-
1
it "adapts one site" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => []
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":84,"vaccines":75,"patients":61}}
-
} ]
-
}
-
}
-
)
-
end
-
-
1
it "adapts one site without conflicting on properties" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => []
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"properties":5,"beds":84,"vaccines":75,"patients":61,"id":1,"lat":2,"lon":3}}
-
} ]
-
}
-
}
-
)
-
end
-
-
1
it "adapts two sites" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => []
-
1
expect(listener).to receive(:add).with :id => 181985, :lat => -47.55442222700955, :lng => 137.5797882218185, :collection_id => 63, :property => []
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":84,"vaccines":75,"patients":61}}
-
}, {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181985,"type":"site","location":{"lat":-47.55442222700955,"lon":137.5797882218185},"properties":{"beds":84,"vaccines":75,"patients":61}}
-
} ]
-
}
-
}
-
)
-
end
-
-
1
it "adapts one site with numeric property on demand" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => ["75"]
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.return_property 'vaccines'
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":84,"vaccines":75,"patients":61}}
-
} ]
-
}
-
}
-
)
-
end
-
-
1
it "adapts one site with numeric property on demand works ok with array in other property" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => ["75"]
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.return_property 'vaccines'
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":[84],"vaccines":75,"patients":[61]}}
-
} ]
-
}
-
}
-
)
-
end
-
-
1
it "adapts one site with numeric property on demand works ok if the property we are looking for is inside sequence" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => ["75"]
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.return_property 'vaccines'
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":84,"vaccines":[75],"patients":61}}
-
} ]
-
}
-
}
-
)
-
end
-
-
1
it "adapts one site with numeric property on demand works ok if the property we are looking has multi values" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => ["75", "76"]
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.return_property 'vaccines'
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" : {"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":84,"vaccines":[75, 76],"patients":61}}
-
} ]
-
}
-
}
-
)
-
end
-
-
-
1
it "should not repeat when parsing more than one site" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 181984, :lat => -37.55442222700955, :lng => 136.5797882218185, :collection_id => 63, :property => ["75", "76"]
-
1
expect(listener).to receive(:add).with :id => 181985, :lat => -35.55442222700955, :lng => 124.5797882218185, :collection_id => 63, :property => ["75"]
-
-
1
adapter = ElasticSearch::SitesAdapter.new listener
-
1
adapter.return_property 'vaccines'
-
1
adapter.parse %(
-
{
-
"took" : 20,
-
"timed_out" : false,
-
"_shards" : {
-
"total" : 55,
-
"successful" : 55,
-
"failed" : 0
-
},
-
"hits" : {
-
"total" : 4,
-
"max_score" : 1.0,
-
"hits" : [ {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181984",
-
"_score" : 1.0, "_source" :
-
{"id":181984,"type":"site","location":{"lat":-37.55442222700955,"lon":136.5797882218185},"properties":{"beds":84,"vaccines":[75, 76],"patients":61}}
-
-
}, {
-
"_index" : "collection_63",
-
"_type" : "site",
-
"_id" : "181985",
-
"_score" : 1.0, "_source" :
-
{"id":181985,"type":"site","location":{"lat":-35.55442222700955,"lon":124.5797882218185},"properties":{"beds":84,"vaccines":[75],"patients":61}}
-
} ]
-
-
}
-
}
-
)
-
end
-
-
1
context ElasticSearch::SitesAdapter::SkipIdListener do
-
1
it "skips id" do
-
1
listener = double('listener')
-
1
expect(listener).not_to receive(:add)
-
1
skip = ElasticSearch::SitesAdapter::SkipIdListener.new listener, 1
-
1
skip.add :id => 1
-
end
-
-
1
it "doesn't skip id" do
-
1
listener = double('listener')
-
1
expect(listener).to receive(:add).with :id => 2
-
1
skip = ElasticSearch::SitesAdapter::SkipIdListener.new listener, 1
-
1
skip.add :id => 2
-
end
-
end
-
end
-
1
require 'spec_helper'
-
1
require 'spec_helper'
-
-
1
describe Field::ElasticsearchConcern do
-
2
let!(:field) { Field::NumericField.make :id => 23 }
-
-
1
it "returns a single field" do
-
1
expect(Field.where_es_code_is("23")).to be_a_kind_of Field
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Field do
-
1
def history_concern_class
-
Field::TextField
-
end
-
-
1
def history_concern_foreign_key
-
'field_id'
-
end
-
-
1
def history_concern_histories
-
'field_histories'
-
end
-
-
1
def history_concern_class_foreign_key
-
'field_id'
-
end
-
-
-
1
it "sanitizes options" do
-
1
field = Field::SelectOneField.make config: {options: [{code: 'foo', label: 'bar'}]}.with_indifferent_access
-
1
expect(field.config.class).to eq(Hash)
-
1
field.config['options'].each do |option|
-
1
expect(option.class).to eq(Hash)
-
end
-
end
-
-
1
it "sanitizes hierarchy" do
-
1
field = Field::HierarchyField.make config: {hierarchy: [{sub: [{}.with_indifferent_access]}]}.with_indifferent_access
-
1
expect(field.config.class).to eq(Hash)
-
1
field.config['hierarchy'].each do |item|
-
1
expect(item.class).to eq(Hash)
-
1
expect(item['sub'].first.class).to eq(Hash)
-
end
-
end
-
-
1
it 'should include kind in json' do
-
1
field = Field::SelectOneField.make config: {options: [{code: 'foo', label: 'bar'}]}.with_indifferent_access
-
1
json = JSON.parse field.to_json
-
1
expect(json["kind"]).to eq('select_one')
-
end
-
-
1
describe "sample value" do
-
1
it "for text are strings" do
-
1
field = Field::TextField.make
-
1
expect(field.sample_value).to be_an_instance_of String
-
1
expect(field.sample_value.length).to be > 0
-
end
-
-
1
it "for numbers is a number" do
-
1
field = Field::NumericField.make
-
1
expect(field.sample_value).to be_a_kind_of Numeric
-
end
-
-
1
it "for dates is a date" do
-
1
field = Field::DateField.make
-
2
expect { field.parse_date(field.sample_value) }.to_not raise_error
-
end
-
-
1
it "for user is a string" do
-
1
user = User.make email: 'an@email.com'
-
1
field = Field::UserField.make
-
1
expect(field.sample_value(user)).to eq(user.email)
-
end
-
-
1
it "for 'select one' is one of the choices" do
-
1
config_options = [{id: 1, code: 'one', label: 'One'}, {id: 2, code: 'two', label: 'Two'}]
-
1
field = Field::SelectOneField.make config: { options: config_options }.with_indifferent_access
-
3
codes = config_options.map { |o| o[:code] }
-
1
expect(codes).to include field.sample_value
-
end
-
-
1
it "for 'select many' are among the choices" do
-
1
config_options = [{id: 1, code: 'one', label: 'One'}, {id: 2, code: 'two', label: 'Two'}, {id: 3, code: 'three', label: 'Three'}]
-
1
field = Field::SelectManyField.make config: { options: config_options }.with_indifferent_access
-
4
codes = config_options.map { |o| o[:code] }
-
1
expect(field.sample_value.length).to be > 0
-
1
field.sample_value.each do |option|
-
2
expect(codes).to include option
-
end
-
end
-
-
1
it "for hierarchy is a valid item" do
-
1
config_hierarchy = [{ id: 0, name: 'root', sub: [{id: 1, name: 'child'}]}]
-
1
field = Field::HierarchyField.make config: { hierarchy: config_hierarchy }.with_indifferent_access
-
1
expect(['root', 'child']).to include field.sample_value
-
end
-
-
1
it "for email and phone is a string" do
-
1
field = Field::EmailField.make
-
1
expect(field.sample_value).to be_an_instance_of String
-
-
1
field = Field::PhoneField.make
-
1
expect(field.sample_value).to be_an_instance_of String
-
end
-
-
1
it "for fields with no config should be the empty string" do
-
1
field = Field::SelectManyField.make config: {}
-
1
expect(field.sample_value).to eq('')
-
-
1
field = Field::SelectOneField.make config: {}
-
1
expect(field.sample_value).to eq('')
-
-
1
field = Field::HierarchyField.make config: {}
-
1
expect(field.sample_value).to eq('')
-
end
-
end
-
-
1
describe "cast strongly type" do
-
6
let!(:config_options) { [{id: 1, code: 'one', label: 'One'}, {id: 2, code: 'two', label: 'Two'}] }
-
-
1
describe "select_one" do
-
2
let!(:field) { Field::SelectOneField.make config: {options: config_options} }
-
-
1
it "should convert value" do
-
1
expect(field.strongly_type('1')).to eq 1
-
end
-
end
-
-
1
describe "select_many" do
-
2
let!(:field) { Field::SelectManyField.make config: {options: config_options} }
-
-
1
it "should convert value to integer" do
-
1
expect(field.strongly_type('1')).to eq 1
-
1
expect(field.strongly_type('2')).to eq 2
-
end
-
end
-
-
1
describe 'yes_no' do
-
3
let!(:field) { Field::YesNoField.make }
-
-
1
it "should convert to 'true'" do
-
1
expect(field.strongly_type('true')).to eq true
-
end
-
-
1
it "should convert to 'false'" do
-
1
expect(field.strongly_type('false')).to eq false
-
1
expect(field.strongly_type(nil)).to eq false
-
end
-
end
-
-
1
describe 'date' do
-
2
let!(:field) { Field::DateField.make }
-
-
1
it "should convert nil" do
-
1
expect(field.strongly_type(nil)).to eq nil
-
end
-
end
-
end
-
-
1
it "should have kind 'user'" do
-
1
expect(Field::UserField.make).to be_valid
-
end
-
-
1
it "should have kind 'email'" do
-
1
expect(Field::EmailField.make).to be_valid
-
end
-
-
1
describe "generate hierarchy options" do
-
1
it "for empty hierarchy" do
-
1
config_hierarchy = []
-
1
field = Field::HierarchyField.make config: { hierarchy: config_hierarchy }.with_indifferent_access
-
1
expect(field.hierarchy_options).to eq([])
-
end
-
-
1
it "for hierarchy with one level" do
-
1
config_hierarchy = [{ id: 0, name: 'root', sub: [{id: 1, name: 'child'}]}]
-
1
field = Field::HierarchyField.make config: { hierarchy: config_hierarchy }.with_indifferent_access
-
1
expect(field.hierarchy_options).to eq([{:id=>0, :name=>"root"}, {:id=>1, :name=>"child"}])
-
end
-
-
1
it "for hierarchy with one level two childs" do
-
1
config_hierarchy = [{ id: 0, name: 'root', sub: [{id: 1, name: 'child'}, {id: 2, name: 'child2'}]}]
-
1
field = Field::HierarchyField.make config: { hierarchy: config_hierarchy }.with_indifferent_access
-
1
expect(field.hierarchy_options).to eq([{:id=>0, :name=>"root"}, {:id=>1, :name=>"child"}, {:id=>2, :name=>"child2"}])
-
end
-
end
-
-
1
describe "validations" do
-
42
let!(:user) { User.make }
-
1
let!(:collection) { user.create_collection Collection.make_unsaved }
-
42
let!(:layer) { collection.layers.make }
-
42
let!(:text) { layer.text_fields.make :code => 'text' }
-
42
let!(:numeric) { layer.numeric_fields.make :code => 'numeric', :config => {} }
-
42
let!(:yes_no) { layer.yes_no_fields.make :code => 'yes_no'}
-
-
1
let!(:numeric_with_decimals) {
-
41
layer.numeric_fields.make :code => 'numeric_with_decimals', :config => {
-
:allows_decimals => "true" }.with_indifferent_access
-
}
-
-
42
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'next_id' => 3, 'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
-
42
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'next_id' => 3, 'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
-
1
config_hierarchy = [{ id: '60', name: 'Dad', sub: [{id: '100', name: 'Son'}, {id: '101', name: 'Bro'}]}]
-
42
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
42
let!(:site_field) { layer.site_fields.make :code => 'site'}
-
42
let!(:date) { layer.date_fields.make :code => 'date' }
-
42
let!(:director) { layer.user_fields.make :code => 'user' }
-
42
let!(:email_field) { layer.email_fields.make :code => 'email' }
-
-
42
let!(:site) {collection.sites.make name: 'Foo old', id: 1234, properties: {} }
-
-
42
let!(:collection) { user.create_collection Collection.make_unsaved }
-
-
1
['name', 'code'].each do |parameter|
-
2
it "should validate uniqueness of #{parameter} in collection" do
-
2
beds = collection.text_fields.make parameter.to_sym => 'beds'
-
2
beds2 = collection.text_fields.make_unsaved parameter.to_sym => 'beds'
-
-
2
expect(beds2).not_to be_valid
-
-
2
collection2 = Collection.make
-
-
2
beds3 = collection2.text_fields.make_unsaved parameter.to_sym => 'beds'
-
2
expect(beds3).to be_valid
-
end
-
end
-
-
1
describe "validations for each field" do
-
-
2
it { expect(numeric.valid_value?(1)).to be_truthy }
-
2
it { expect(numeric.valid_value?("1")).to be_truthy }
-
-
2
it { expect(numeric_with_decimals.valid_value?(1.5)).to be_truthy }
-
2
it { expect(numeric_with_decimals.valid_value?("1.5")).to be_truthy }
-
-
2
it { expect(yes_no.valid_value?(true)).to be_truthy }
-
2
it { expect(yes_no.valid_value?(false)).to be_truthy }
-
-
2
it { expect(date.valid_value?("2012-11-27T00:00:00Z")).to be_truthy }
-
-
2
it { expect(hierarchy.valid_value?("101")).to be_truthy }
-
-
2
it { expect(select_many.valid_value?([1,2])).to be_truthy }
-
2
it { expect(select_many.valid_value?(["1","2"])).to be_truthy }
-
-
2
it { expect(select_one.valid_value?(1)).to be_truthy }
-
2
it { expect(select_one.valid_value?("1")).to be_truthy }
-
-
2
it { expect(site_field.valid_value?(1234)).to be_truthy }
-
2
it { expect(site_field.valid_value?("1234")).to be_truthy }
-
-
2
it { expect(director.valid_value?(user.email)).to be_truthy }
-
-
2
it { expect(email_field.valid_value?("myemail@resourcemap.com")).to be_truthy }
-
end
-
-
1
describe "decode from ImportWizard format" do
-
-
2
it { expect(numeric.decode(1)).to eq(1) }
-
2
it { expect(numeric.decode("1")).to eq(1) }
-
-
2
it { expect(numeric_with_decimals.decode("1.5")).to eq(1.5) }
-
-
2
it { expect(yes_no.decode("true")).to eq(true) }
-
-
2
it { expect(date.decode("12/26/1988")).to eq("1988-12-26T00:00:00Z") }
-
-
2
it { expect(hierarchy.decode("Dad")).to eq("60") }
-
-
2
it { expect(select_one.decode("one")).to eq(1) }
-
2
it { expect(select_one.decode("One")).to eq(1) }
-
-
2
it { expect(select_many.decode("one")).to eq([1]) }
-
2
it { expect(select_many.decode("One")).to eq([1]) }
-
2
it { expect(select_many.decode(['one', 'two'])).to eq([1, 2]) }
-
2
it { expect(select_many.decode("one,two")).to eq([1, 2]) }
-
-
end
-
-
# TODO: Delete apply_format_and_validate method and use it's content instead with the corresponding decode
-
# decode_fred or decode (for import_wizard)
-
1
describe "apply_format_and_validate" do
-
-
1
it "should validate format for numeric field" do
-
1
expect(numeric.apply_format_and_validate(2, false, collection)).to be(2)
-
1
expect(numeric.apply_format_and_validate("2", false, collection)).to be(2)
-
2
expect { numeric.apply_format_and_validate("invalid23", false, collection) }.to raise_error(RuntimeError, "Invalid numeric value in field numeric. This numeric field is configured not to allow decimal values.")
-
end
-
-
1
it "should validate format for yes_no field" do
-
1
expect(yes_no.apply_format_and_validate(true, false, collection)).to be_truthy
-
1
expect(yes_no.apply_format_and_validate(1, false, collection)).to be_truthy
-
1
expect(yes_no.apply_format_and_validate("true", false, collection)).to be_truthy
-
1
expect(yes_no.apply_format_and_validate("yes", false, collection)).to be_truthy
-
1
expect(yes_no.apply_format_and_validate("1", false, collection)).to be_truthy
-
1
expect(yes_no.apply_format_and_validate(0, false, collection)).to be_falsey
-
1
expect(yes_no.apply_format_and_validate("0", false, collection)).to be_falsey
-
1
expect(yes_no.apply_format_and_validate("false", false, collection)).to be_falsey
-
end
-
-
1
it "should not allow decimals" do
-
2
expect { numeric.apply_format_and_validate("2.3", false, collection) }.to raise_error(RuntimeError, "Invalid numeric value in field #{numeric.code}. This numeric field is configured not to allow decimal values.")
-
2
expect { numeric.apply_format_and_validate(2.3, false, collection) }.to raise_error(RuntimeError, "Invalid numeric value in field #{numeric.code}. This numeric field is configured not to allow decimal values.")
-
end
-
-
1
it "should allow decimals" do
-
1
expect(numeric_with_decimals.apply_format_and_validate("2.3", false, collection)).to eq(2.3)
-
1
expect(numeric_with_decimals.apply_format_and_validate(2.3, false, collection)).to eq(2.3)
-
end
-
-
1
it "should validate format for date field" do
-
1
expect(date.apply_format_and_validate("11/27/2012",false, collection)).to eq("2012-11-27T00:00:00Z")
-
2
expect { date.apply_format_and_validate("27/10/1298", false, collection) }.to raise_error(RuntimeError, "Invalid date value in field #{date.code}")
-
2
expect { date.apply_format_and_validate("11/27", false, collection) }.to raise_error(RuntimeError, "Invalid date value in field #{date.code}")
-
2
expect { date.apply_format_and_validate("invalid", false, collection) }.to raise_error(RuntimeError, "Invalid date value in field #{date.code}")
-
end
-
-
1
it "should validate format for hierarchy field" do
-
1
expect(hierarchy.apply_format_and_validate("Dad", false, collection)).to eq("60")
-
2
expect { hierarchy.apply_format_and_validate("invalid", false, collection) }.to raise_error(RuntimeError, "Invalid hierarchy option in field #{hierarchy.code}")
-
end
-
-
1
it "should validate format for select_one field" do
-
1
expect(select_one.apply_format_and_validate("one", false, collection)).to eq(1)
-
1
expect(select_one.apply_format_and_validate("One", false, collection)).to eq(1)
-
2
expect { select_one.apply_format_and_validate("invalid", false, collection) }.to raise_error(RuntimeError, "Invalid option in field #{select_one.code}")
-
end
-
-
1
it "should validate format for select_many field" do
-
1
expect(select_many.apply_format_and_validate(["two", "one"], false, collection)).to eq([2, 1])
-
2
expect { select_many.apply_format_and_validate(["two","inv"], false, collection) }.to raise_error(RuntimeError, "Invalid option 'inv' in field #{select_many.code}")
-
2
expect { select_many.apply_format_and_validate("invalid", false, collection) }.to raise_error(RuntimeError, "Invalid option 'invalid' in field #{select_many.code}")
-
end
-
-
1
it "should validate format for site field" do
-
1
expect(site_field.apply_format_and_validate(1234, false, collection)).to eq(1234)
-
1
expect(site_field.apply_format_and_validate("1234", false, collection)).to eq("1234")
-
2
expect { site_field.apply_format_and_validate(124, false, collection) }.to raise_error(RuntimeError, "Non-existent site-id in field #{site_field.code}")
-
2
expect { site_field.apply_format_and_validate("124inv", false, collection) }.to raise_error(RuntimeError, "Non-existent site-id in field #{site_field.code}")
-
end
-
-
1
it "should validate format for user field" do
-
1
expect(director.apply_format_and_validate(user.email, false, collection)).to eq(user.email)
-
2
expect { director.apply_format_and_validate("inexisting@email.com", false, collection) }.to raise_error(RuntimeError, "Non-existent user email address in field #{director.code}")
-
end
-
-
1
it "should validate format for email field" do
-
1
expect(email_field.apply_format_and_validate("valid@email.com", false, collection)).to eq("valid@email.com")
-
2
expect { email_field.apply_format_and_validate("s@@email.c.om", false, collection) }.to raise_error(RuntimeError, "Invalid email address in field #{email_field.code}")
-
end
-
end
-
end
-
-
1
describe "dbf_field" do
-
4
let(:user) { User.make }
-
4
let(:collection) { user.create_collection Collection.make_unsaved }
-
4
let(:layer) { collection.layers.make }
-
2
let(:field) { layer.yes_no_fields.make :code => 'yes_no'}
-
-
1
it "should convert to C dbf field" do
-
1
expect(field.to_dbf_field.type).to eq('C')
-
end
-
-
1
context "numeric field" do
-
2
let(:field) { layer.numeric_fields.make :code => 'numeric', :config => {} }
-
-
1
it "should convert to N dbf field" do
-
1
expect(field.to_dbf_field.type).to eq('N')
-
end
-
-
1
context "with decimal value allowed" do
-
2
let(:field) { layer.numeric_fields.make :code => 'numeric', :config => {allows_decimals: "true"} }
-
-
1
it "should convert to N dbf field with decimal" do
-
1
dbf_field = field.to_dbf_field
-
-
expect(dbf_field.type).to eq('N')
-
expect(dbf_field.decimal).to be > 0
-
end
-
end
-
end
-
end
-
-
1
describe 'telemetry' do
-
4
let!(:collection) { Collection.make }
-
4
let!(:layer) { Layer.make collection: collection }
-
-
1
it 'should touch collection lifespan on create' do
-
1
field = Field::NumericField.make_unsaved collection: collection, layer: layer
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
field.save
-
end
-
-
1
it 'should touch collection lifespan on update' do
-
1
field = Field::NumericField.make collection: collection, layer: layer
-
1
field.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
field.save
-
end
-
-
1
it 'should touch collection lifespan on destroy' do
-
1
field = Field::NumericField.make collection: collection, layer: layer
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
field.destroy
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe HashParser do
-
1
before(:each) do
-
3
@xml = StringIO.new("<site><lat>12.1</lat><lng>11.1</lng></site>")
-
3
@incorrect_xml = StringIO.new("<site><lat>12.1</lat><lng>11.1</lng>")
-
end
-
-
1
it "should raise exception 'missing xml file'" do
-
2
expect { HashParser.from_xml_file(nil)}.to raise_error("missing xml file")
-
end
-
-
1
it "should raise exception 'invalid xml format'" do
-
2
expect { HashParser.from_xml_file(@incorrect_xml)}.to raise_error("invalid xml format")
-
end
-
-
1
it "should convert xml to hash object" do
-
1
result = HashParser.from_xml_file @xml
-
1
expect(result).to be_a_kind_of(Hash)
-
end
-
end
-
# encoding: UTF-8
-
1
require 'spec_helper'
-
-
1
describe ImportWizard do
-
53
let!(:user) { User.make }
-
-
53
let!(:collection) { user.create_collection Collection.make_unsaved }
-
53
let!(:user2) { collection.users.make :email => 'user2@email.com'}
-
53
let!(:membership) { collection.memberships.create! :user_id => user2.id }
-
-
53
let!(:layer) { collection.layers.make }
-
-
53
let!(:text) { layer.text_fields.make :code => 'text' }
-
53
let!(:numeric) { layer.numeric_fields.make :code => 'numeric'}
-
53
let!(:yes_no) { layer.yes_no_fields.make :code => 'yes_no' }
-
53
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'next_id' => 3, 'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
53
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'next_id' => 3, 'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
1
config_hierarchy = [{ id: '60', name: 'Dad', sub: [{id: '100', name: 'Son'}, {id: '101', name: 'Bro'}]}]
-
53
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
53
let!(:site) { layer.site_fields.make :code => 'site'}
-
53
let!(:date) { layer.date_fields.make :code => 'date' }
-
53
let!(:director) { layer.user_fields.make :code => 'user' }
-
-
1
it "imports with name, lat, lon and one new numeric property" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Lat', 'Lon', 'Beds']
-
1
csv << ['Foo', '1.2', '3.4', '10']
-
1
csv << ['Bar', '5.6', '7.8', '20']
-
1
csv << ['', '', '', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Lat', use_as: 'lat'},
-
{header: 'Lon', use_as: 'lng'},
-
{header: 'Beds', use_as: 'new_field', kind: 'numeric', code: 'beds', label: 'The beds'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(2)
-
1
expect(layers[1].name).to eq('Import wizard')
-
-
1
fields = layers[1].fields
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0].name).to eq('The beds')
-
1
expect(fields[0].code).to eq('beds')
-
1
expect(fields[0].kind).to eq('numeric')
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({fields[0].es_code => 10})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({fields[0].es_code => 20})
-
end
-
-
1
it "import should calculate collection bounds from sites" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Lat', 'Lon']
-
1
csv << ['Foo', '30.0', '20.0']
-
1
csv << ['Bar', '40.0', '30.0']
-
1
csv << ['FooBar', '45.0', '40.0']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Lat', use_as: 'lat'},
-
{header: 'Lon', use_as: 'lng'}
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
collection.reload
-
1
expect(collection.min_lat.to_f).to eq(30.0)
-
1
expect(collection.max_lat.to_f).to eq(45.0)
-
1
expect(collection.min_lng.to_f).to eq(20.0)
-
1
expect(collection.max_lng.to_f).to eq(40.0)
-
1
expect(collection.lat.to_f).to eq(37.5)
-
1
expect(collection.lng.to_f).to eq(30.0)
-
end
-
-
1
it "imports with name, lat, lon and one new numeric property and existing ID" do
-
1
site1 = collection.sites.make name: 'Foo old', properties: {text.es_code => 'coco'}
-
1
site2 = collection.sites.make name: 'Bar old', properties: {text.es_code => 'lala'}
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', 'Lat', 'Lon', 'Beds']
-
1
csv << ["#{site1.id}", 'Foo', '1.2', '3.4', '10']
-
1
csv << ["#{site2.id}", 'Bar', '5.6', '7.8', '20']
-
1
csv << ['', '', '', '', '']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: 'id'},
-
{header: 'Name', use_as: 'name'},
-
{header: 'Lat', use_as: 'lat'},
-
{header: 'Lon', use_as: 'lng'},
-
{header: 'Beds', use_as: 'new_field', kind: 'numeric', code: 'beds', label: 'The beds'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(2)
-
1
expect(layers[1].name).to eq('Import wizard')
-
-
1
fields = layers[1].fields
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0].name).to eq('The beds')
-
1
expect(fields[0].code).to eq('beds')
-
1
expect(fields[0].kind).to eq('numeric')
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
site1.reload
-
1
expect(site1.name).to eq('Foo')
-
1
expect(site1.properties).to eq({fields[0].es_code => 10, text.es_code => 'coco'})
-
-
1
site2.reload
-
1
expect(site2.name).to eq('Bar')
-
1
expect(site2.properties).to eq({fields[0].es_code => 20, text.es_code => 'lala'})
-
end
-
-
1
it "imports with name, lat, lon and one new numeric property and existing ID empty" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', 'Lat', 'Lon', 'Beds']
-
1
csv << ["", 'Foo', '1.2', '3.4', '10']
-
1
csv << ['', '', '', '', '']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: 'id'},
-
{header: 'Name', use_as: 'name'},
-
{header: 'Lat', use_as: 'lat'},
-
{header: 'Lon', use_as: 'lng'},
-
{header: 'Beds', use_as: 'new_field', kind: 'numeric', code: 'beds', label: 'The beds'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(2)
-
1
expect(layers[1].name).to eq('Import wizard')
-
-
1
fields = layers[1].fields
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0].name).to eq('The beds')
-
1
expect(fields[0].code).to eq('beds')
-
1
expect(fields[0].kind).to eq('numeric')
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(1)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({fields[0].es_code => 10})
-
end
-
-
1
it "imports with new select one mapped to both code and label" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Visibility']
-
1
csv << ['Foo', 'public']
-
1
csv << ['Bar', 'private']
-
1
csv << ['Baz', 'private']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Visibility', use_as: 'new_field', kind: 'select_one', code: 'visibility', label: 'The visibility', selectKind: 'both'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(2)
-
1
expect(layers[1].name).to eq('Import wizard')
-
-
1
fields = layers[1].fields
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0].name).to eq('The visibility')
-
1
expect(fields[0].code).to eq('visibility')
-
1
expect(fields[0].kind).to eq('select_one')
-
1
expect(fields[0].config).to eq('next_id' => 3, 'options' => [{'id' => 1, 'code' => 'public', 'label' => 'public'}, {'id' => 2, 'code' => 'private', 'label' => 'private'}])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(3)
-
-
1
expect(sites[0].properties).to eq({fields[0].es_code => 1})
-
1
expect(sites[1].properties).to eq({fields[0].es_code => 2})
-
1
expect(sites[2].properties).to eq({fields[0].es_code => 2})
-
end
-
-
1
it "imports with two new select ones mapped to code and label" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Visibility', 'Visibility Code']
-
1
csv << ['Foo', 'public', '1']
-
1
csv << ['Bar', 'private', '0']
-
1
csv << ['Baz', 'private', '0']
-
1
csv << ['', '', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Visibility', use_as: 'new_field', kind: 'select_one', code: 'visibility', label: 'The visibility', selectKind: 'label'},
-
{header: 'Visibility Code', use_as: 'new_field', kind: 'select_one', code: 'visibility', label: 'The visibility', selectKind: 'code'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(2)
-
1
expect(layers[1].name).to eq('Import wizard')
-
-
1
fields = layers[1].fields
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0].name).to eq('The visibility')
-
1
expect(fields[0].code).to eq('visibility')
-
1
expect(fields[0].kind).to eq('select_one')
-
1
expect(fields[0].config).to eq('next_id' => 3, 'options' => [{'id' => 1, 'code' => '1', 'label' => 'public'}, {'id' => 2, 'code' => '0', 'label' => 'private'}])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(3)
-
-
1
expect(sites[0].properties).to eq({fields[0].es_code => 1})
-
1
expect(sites[1].properties).to eq({fields[0].es_code => 2})
-
1
expect(sites[2].properties).to eq({fields[0].es_code => 2})
-
end
-
-
1
it "imports with name and existing text property" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', 'hi']
-
1
csv << ['Bar', 'bye']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: text.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({text.es_code => 'hi'})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({text.es_code => 'bye'})
-
end
-
-
1
it "imports with name and existing numeric property" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', '10']
-
1
csv << ['Bar', '20']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: numeric.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({numeric.es_code => 10})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({numeric.es_code => 20})
-
end
-
-
1
it "imports with name and existing select_one property" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', 'one']
-
1
csv << ['Bar', 'two']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: select_one.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({select_one.es_code => 1})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({select_one.es_code => 2})
-
end
-
-
1
it "imports with name and existing select_many property" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', 'one']
-
1
csv << ['Bar', 'one, two']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: select_many.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({select_many.es_code => [1]})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({select_many.es_code => [1, 2]})
-
end
-
-
1
it "should update hierarchy fields in bulk update using name" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', 'Son']
-
1
csv << ['Bar', 'Bro']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: hierarchy.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
1
sites = collection.sites.reload
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({hierarchy.es_code => "100"})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({hierarchy.es_code => "101"})
-
end
-
-
# The updates will be performed using the hierarchy name for now
-
# but soon they this is going to change when solving Issue #459
-
1
it "should update hierarchy fields in bulk update using id" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', 'Son']
-
1
csv << ['Bar', 'Bro']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: hierarchy.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
1
sites = collection.sites.reload
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({hierarchy.es_code => "100"})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({hierarchy.es_code => "101"})
-
end
-
-
-
1
it "imports with name and existing date property" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', '12/24/2012']
-
1
csv << ['Bar', '10/23/2033']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: date.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Foo')
-
1
expect(sites[0].properties).to eq({date.es_code => "2012-12-24T00:00:00Z"})
-
-
1
expect(sites[1].name).to eq('Bar')
-
1
expect(sites[1].properties).to eq({date.es_code => "2033-10-23T00:00:00Z"})
-
end
-
-
1
it "imports with name and existing site property" do
-
-
1
collection.sites.make :name => 'Site1', :id => '123'
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Column']
-
1
csv << ['Foo', '123']
-
1
csv << ['', '']
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Column', use_as: 'existing_field', field_id: site.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
expect(collection.layers).to eq([layer])
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
expect(sites[0].name).to eq('Site1')
-
-
1
expect(sites[1].name).to eq('Foo')
-
1
expect(sites[1].properties).to eq({site.es_code => "123"})
-
end
-
-
1
it "should update all property values" do
-
1
site1 = collection.sites.make name: 'Foo old', id: 1234, properties: {
-
text.es_code => 'coco',
-
numeric.es_code => 10,
-
yes_no.es_code => true,
-
select_one.es_code => 1,
-
select_many.es_code => [1, 2],
-
hierarchy.es_code => 60,
-
date.es_code => "2012-10-24T00:00:00Z",
-
director.es_code => user.email
-
}
-
1
site1.properties[site.es_code] = site1.id
-
-
1
site2 = collection.sites.make name: 'Bar old', properties: {text.es_code => 'lala'}, id: 1235
-
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', 'Lat', 'Lon', 'Text', 'Numeric', 'Yes no', 'Select One', 'Select Many', 'Hierarchy', 'Site', 'Date', 'User']
-
1
csv << ["#{site1.id}", 'Foo new', '1.2', '3.4', 'new val', 11, 'no', 'two', 'two, one', 'Dad', 1235, '12/26/1988', 'user2@email.com']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: 'id'},
-
{header: 'Name', use_as: 'name'},
-
{header: 'Text', use_as: 'existing_field', field_id: text.id},
-
{header: 'Numeric', use_as: 'existing_field', field_id: numeric.id},
-
{header: 'Yes no', use_as: 'existing_field', field_id: yes_no.id},
-
{header: 'Select One', use_as: 'existing_field', field_id: select_one.id},
-
{header: 'Select Many', use_as: 'existing_field', field_id: select_many.id},
-
{header: 'Hierarchy', use_as: 'existing_field', field_id: hierarchy.id},
-
{header: 'Site', use_as: 'existing_field', field_id: site.id},
-
{header: 'Date', use_as: 'existing_field', field_id: date.id},
-
{header: 'User', use_as: 'existing_field', field_id: director.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(1)
-
1
expect(layers[0].name).to eq(layer.name)
-
-
1
fields = layers[0].fields
-
1
expect(fields.length).to eq(9)
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
site1.reload
-
1
expect(site1.name).to eq('Foo new')
-
1
expect(site1.properties).to eq({
-
text.es_code => 'new val',
-
numeric.es_code => 11,
-
yes_no.es_code => false,
-
select_one.es_code => 2,
-
select_many.es_code => [2, 1],
-
hierarchy.es_code => '60',
-
site.es_code => '1235',
-
date.es_code => "1988-12-26T00:00:00Z",
-
director.es_code => 'user2@email.com'
-
})
-
-
1
site2.reload
-
1
expect(site2.name).to eq('Bar old')
-
1
expect(site2.properties).to eq({text.es_code => 'lala'})
-
end
-
-
1
it "should delete all property values" do
-
1
site1 = collection.sites.make name: 'Foo old', id: 1234, properties: {
-
text.es_code => 'coco',
-
numeric.es_code => 10,
-
select_one.es_code => 1,
-
select_many.es_code => [1, 2],
-
hierarchy.es_code => 60,
-
date.es_code => "2012-10-24T00:00:00Z",
-
director.es_code => user.email
-
}
-
1
site1.properties[site.es_code] = site1.id
-
-
-
1
site2 = collection.sites.make name: 'Bar old', properties: {text.es_code => 'lala'}, id: 1235
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', 'Lat', 'Lon', 'Text', 'Numeric', 'Select One', 'Select Many', 'Hierarchy', 'Site', 'Date', 'User']
-
1
csv << ["#{site1.id}", 'Foo old', '1.2', '3.4', '', '', '', '', '', '', '', '']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: 'id'},
-
{header: 'Name', use_as: 'name'},
-
{header: 'Text', use_as: 'existing_field', field_id: text.id},
-
{header: 'Numeric', use_as: 'existing_field', field_id: numeric.id},
-
{header: 'Select One', use_as: 'existing_field', field_id: select_one.id},
-
{header: 'Select Many', use_as: 'existing_field', field_id: select_many.id},
-
{header: 'Hierarchy', use_as: 'existing_field', field_id: hierarchy.id},
-
{header: 'Site', use_as: 'existing_field', field_id: site.id},
-
{header: 'Date', use_as: 'existing_field', field_id: date.id},
-
{header: 'User', use_as: 'existing_field', field_id: director.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(1)
-
1
expect(layers[0].name).to eq(layer.name)
-
-
1
fields = layers[0].fields
-
1
expect(fields.length).to eq(9)
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
site1.reload
-
1
expect(site1.name).to eq('Foo old')
-
1
expect(site1.properties).to eq({})
-
-
1
site2.reload
-
1
expect(site2.name).to eq('Bar old')
-
1
expect(site2.properties).to eq({text.es_code => 'lala'})
-
end
-
-
1
it "should not create a new hierarchy field in import wizard" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Hierarchy']
-
1
csv << ['Dad']
-
end
-
-
1
specs = [
-
{header: 'Hierarchy', use_as: 'new_field', kind: 'hierarchy', code: 'new_hierarchy'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
2
expect { ImportWizard.execute(user, collection, specs) }.to raise_error
-
-
end
-
-
1
it "should create new fields with all property values" do
-
1
site1 = collection.sites.make name: 'Foo old', id: 1234, properties: {}
-
-
1
site2 = collection.sites.make name: 'Bar old', properties: {}, id: 1235
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', 'Lat', 'Lon', 'Text', 'Numeric', 'Yes no', 'Select One', 'Select Many', 'Site', 'Date', 'User', 'Email', 'Phone']
-
1
csv << ["#{site1.id}", 'Foo new', '1.2', '3.4', 'new val', 11, 'no', 'two', 'two, one', 1235, '12/26/1988', 'user2@email.com', 'new@email.com', '1456']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: 'id'},
-
{header: 'Name', use_as: 'name'},
-
{header: 'Text', use_as: 'new_field', kind: 'text', code: 'new_text'},
-
{header: 'Numeric', use_as: 'new_field', kind: 'numeric', code: 'new_numeric'},
-
{header: 'Yes no', use_as: 'new_field', kind: 'yes_no', code: 'new_yes_no'},
-
{header: 'Select One', use_as: 'new_field', kind: 'select_one', code: 'new_select_one', label: 'New Select One', selectKind: 'both'},
-
{header: 'Select Many', use_as: 'new_field', kind: 'select_many', code: 'new_select_many', label: 'New Select Many', selectKind: 'both'},
-
{header: 'Site', use_as: 'new_field', kind: 'site', code: 'new_site'},
-
{header: 'Date', use_as: 'new_field', kind: 'date', code: 'new_date'},
-
{header: 'User', use_as: 'new_field', kind: 'user', code: 'new_user'},
-
{header: 'Email', use_as: 'new_field', kind: 'email', code: 'new_email'},
-
{header: 'Phone', use_as: 'new_field', kind: 'phone', code: 'new_phone'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
ImportWizard.execute user, collection, specs
-
-
1
layers = collection.layers
-
1
expect(layers.length).to eq(2)
-
-
3
new_layer = layers.detect{|l| l.name == "Import wizard"}
-
-
1
fields = new_layer.fields
-
1
expect(fields.length).to eq(10)
-
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(2)
-
-
1
site1.reload
-
1
expect(site1.name).to eq('Foo new')
-
1
expect(site1.properties.length).to eq(10)
-
1
expect(site1.properties[yes_no.es_code]).to be_falsey
-
-
1
site2.reload
-
1
expect(site2.name).to eq('Bar old')
-
1
expect(site2.properties).to eq({})
-
end
-
-
1
it "should guess column spec for existing fields" do
-
1
email_field = layer.email_fields.make :code => 'email'
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', 'Lat', 'Lon', 'text', 'numeric', 'select_one', 'select_many', 'hierarchy', 'site', 'date', 'user', 'email']
-
1
csv << ["123", 'Foo old', '1.2', '3.4', '', '', 'two', 'two', 'uno', 1235, '12/26/1988', 'user2@email.com', 'email@mail.com']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
-
1
expect(column_spec.length).to eq(13)
-
-
1
expect(column_spec).to include({:header=>"resmap-id", :kind=> :id, :code=>"resmap-id", :label=>"Resmap", :use_as=>:id})
-
1
expect(column_spec).to include({:header=>"Name", :kind=>:name, :code=>"name", :label=>"Name", :use_as=>:name})
-
1
expect(column_spec).to include({:header=>"Lat", :kind=>:location, :code=>"lat", :label=>"Lat", :use_as=>:lat})
-
1
expect(column_spec).to include({:header=>"Lon", :kind=>:location, :code=>"lon", :label=>"Lon", :use_as=>:lng})
-
1
expect(column_spec).to include({:header=>"text", :kind=>:text, :code=>"text", :label=>"Text", :use_as=>:existing_field, :layer_id=> text.layer_id, :field_id=>text.id})
-
1
expect(column_spec).to include({:header=>"numeric", :kind=>:numeric, :code=>"numeric", :label=>"Numeric", :use_as=>:existing_field, :layer_id=>numeric.layer_id, :field_id=>numeric.id})
-
1
expect(column_spec).to include({:header=>"select_one", :kind=>:select_one, :code=>"select_one", :label=>"Select One", :use_as=>:existing_field, :layer_id=>select_one.layer_id, :field_id=>select_one.id})
-
1
expect(column_spec).to include({:header=>"select_many", :kind=>:select_many, :code=>"select_many", :label=>"Select Many", :use_as=>:existing_field, :layer_id=>select_many.layer_id, :field_id=>select_many.id})
-
1
expect(column_spec).to include({:header=>"hierarchy", :kind=>:hierarchy, :code=>"hierarchy", :label=>"Hierarchy", :use_as=>:existing_field, :layer_id=>hierarchy.layer_id, :field_id=>hierarchy.id})
-
1
expect(column_spec).to include({:header=>"site", :kind=>:site, :code=>"site", :label=>"Site", :use_as=>:existing_field, :layer_id=>site.layer_id, :field_id=>site.id})
-
1
expect(column_spec).to include({:header=>"date", :kind=>:date, :code=>"date", :label=>"Date", :use_as=>:existing_field, :layer_id=>date.layer_id, :field_id=>date.id})
-
1
expect(column_spec).to include({:header=>"user", :kind=>:user, :code=>"user", :label=>"User", :use_as=>:existing_field, :layer_id=>director.layer_id, :field_id=>director.id})
-
1
expect(column_spec).to include({:header=>"email", :kind=>:email, :code=>"email", :label=>"Email", :use_as=>:existing_field, :layer_id=>email_field.layer_id, :field_id=>email_field.id})
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
1
it "should get sites & errors for invalid existing fields" do
-
1
email_field = layer.email_fields.make :code => 'email'
-
1
site2 = collection.sites.make name: 'Bar old', properties: {text.es_code => 'lala'}, id: 1235
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['text', 'numeric', 'select_one', 'select_many', 'hierarchy', 'site', 'date', 'user', 'email']
-
1
csv << ['new val', '11', 'two', 'one', 'Dad', '1235', '12/26/1988', 'user2@email.com', 'email@mail.com']
-
1
csv << ['new val', 'invalid11', 'inval', 'Dad, inv', 'inval', '999', '12/26', 'non-existing@email.com', 'email@ma@il.com']
-
1
csv << ['new val', 'invalid11', 'inval', 'Dad, inv', 'inval', '999', '12/26', 'non-existing@email.com', 'email@ma@il.com']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
1
processed_sites = (ImportWizard.validate_sites_with_columns user, collection, column_spec)
-
1
sites_preview = processed_sites[:sites]
-
-
1
expect(sites_preview.length).to eq(3)
-
1
first_line = sites_preview.first
-
1
expect(first_line).to eq([{:value=>"new val"}, {value: '11'}, {:value=>"two"}, {:value=>"one"}, {:value=>"Dad"},
-
{:value=>"1235"}, {:value=>"12/26/1988"}, {:value=>"user2@email.com"}, {:value=>"email@mail.com"}])
-
-
#Lines 2 and 3 are equals
-
1
second_line = sites_preview.last
-
1
expect(second_line).to eq([{:value=>"new val"}, {:value=>"invalid11"}, {:value=>"inval"}, {:value=>"Dad, inv"}, {:value=>"inval"},
-
{:value=>"999"}, {:value=>"12/26"}, {:value=>"non-existing@email.com"}, {:value=>"email@ma@il.com"}])
-
-
1
sites_errors = processed_sites[:errors]
-
-
1
data_errors = sites_errors[:data_errors]
-
1
expect(data_errors.length).to eq(8)
-
-
1
expect(data_errors[0][:description]).to eq("Some of the values in column 2 are not valid for the type numeric.")
-
1
expect(data_errors[0][:type]).to eq('numeric values')
-
1
expect(data_errors[0][:column]).to eq(1)
-
1
expect(data_errors[0][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[1][:description]).to eq("Some of the values in column 3 don't match any existing option.")
-
1
expect(data_errors[1][:column]).to eq(2)
-
1
expect(data_errors[1][:type]).to eq('option values')
-
1
expect(data_errors[1][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[2][:description]).to eq("Some of the values in column 4 don't match any existing option.")
-
1
expect(data_errors[2][:column]).to eq(3)
-
1
expect(data_errors[2][:type]).to eq('option values')
-
1
expect(data_errors[2][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[3][:description]).to eq("Some of the values in column 5 don't exist in the corresponding hierarchy.")
-
1
expect(data_errors[3][:column]).to eq(4)
-
1
expect(data_errors[3][:type]).to eq('values that can be found in the defined hierarchy')
-
1
expect(data_errors[3][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[4][:description]).to eq("Some of the values in column 6 don't match any existing site id in this collection.")
-
1
expect(data_errors[4][:column]).to eq(5)
-
1
expect(data_errors[4][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[5][:description]).to eq("Some of the values in column 7 are not valid for the type date.")
-
1
expect(data_errors[5][:column]).to eq(6)
-
1
expect(data_errors[5][:type]).to eq('dates')
-
1
expect(data_errors[5][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[6][:description]).to eq("Some of the values in column 8 don't match any email address of a member of this collection.")
-
1
expect(data_errors[6][:column]).to eq(7)
-
1
expect(data_errors[6][:type]).to eq('email addresses')
-
1
expect(data_errors[6][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[7][:description]).to eq("Some of the values in column 9 are not valid for the type email.")
-
1
expect(data_errors[7][:column]).to eq(8)
-
1
expect(data_errors[7][:type]).to eq('email addresses')
-
1
expect(data_errors[7][:rows]).to eq([1, 2])
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
1
it "should be include hints for format errors" do
-
1
email_field = layer.email_fields.make :code => 'email'
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['numeric', 'date', 'email', 'hierarchy']
-
1
csv << ['11', '12/26/1988', 'email@mail.com', 'Dad']
-
1
csv << ['invalid11', '23/1/234', 'email@ma@il.com', 'invalid']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
1
sites_errors = (ImportWizard.validate_sites_with_columns user, collection, column_spec)[:errors]
-
-
1
data_errors = sites_errors[:data_errors]
-
-
1
expect(data_errors[0][:example]).to eq("Values must be integers.")
-
1
expect(data_errors[1][:example]).to eq("Example of valid date: 1/25/2013.")
-
1
expect(data_errors[2][:example]).to eq("Example of valid email: myemail@resourcemap.com.")
-
1
expect(data_errors[3][:example]).to eq("Some valid values for this hierarchy are: Dad, Son, Bro.")
-
end
-
-
1
it "should get sites & errors for invalid existing fields if field_id is string" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Numeric']
-
1
csv << ['invalid']
-
end
-
-
1
specs = [
-
{header: 'Numeric', use_as: 'existing_field', field_id: "#{numeric.id}"},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
errors = (ImportWizard.validate_sites_with_columns user, collection, specs)[:errors]
-
-
1
data_errors = errors[:data_errors]
-
1
expect(data_errors.length).to eq(1)
-
-
end
-
-
1
it "should get error for invalid new fields" do
-
1
site2 = collection.sites.make name: 'Bar old', properties: {text.es_code => 'lala'}, id: 1235
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['text', 'numeric', 'select_one', 'select_many', 'hierarchy', 'site', 'date', 'user', 'email']
-
1
csv << ['new val', '11', 'two', 'one', 'Dad', '1235', '12/26/1988', 'user2@email.com', 'email@mail.com']
-
1
csv << ['new val', 'invalid11', 'inval', 'Dad, inv', 'inval', '999', '12/26', 'non-existing@email.com', 'email@ma@il.com']
-
1
csv << ['new val', 'invalid11', '', '', '', '', '12/26', '', 'email@ma@il.com']
-
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
1
column_spec = [
-
{header: 'Text', use_as: 'new_field', kind: 'text', code: 'text2', label: 'text2'},
-
{header: 'Numeric', use_as: 'new_field', kind: 'numeric', code: 'numeric2', label: 'numeric2'},
-
{header: 'Select One', use_as: 'new_field', kind: 'select_one', code: 'select_one2', label: 'select_one2'},
-
{header: 'Select Many', use_as: 'new_field', kind: 'select_many', code: 'select_many2', label: 'select_many2'},
-
{header: 'Hierarchy', use_as: 'new_field', kind: 'hierarchy', code: 'hierarchy2', label: 'hierarchy2'},
-
{header: 'Site', use_as: 'new_field', kind: 'site', code: 'site2', label: 'site2'},
-
{header: 'Date', use_as: 'new_field', kind: 'date', code: 'date2', label: 'date2'},
-
{header: 'User', use_as: 'new_field', kind: 'user', code: 'user2', label: 'user2'},
-
{header: 'Email', use_as: 'new_field', kind: 'email', code: 'email2', label: 'email2'},
-
]
-
-
1
sites = (ImportWizard.validate_sites_with_columns user, collection, column_spec)
-
1
sites_preview = sites[:sites]
-
-
1
expect(sites_preview.length).to eq(3)
-
1
first_line = sites_preview.first
-
1
expect(first_line).to eq([{:value=>"new val"}, {value: '11'}, {:value=>"two"}, {:value=>"one"}, {:value=>"Dad"},
-
{:value=>"1235"}, {:value=>"12/26/1988"}, {:value=>"user2@email.com"}, {:value=>"email@mail.com"}])
-
-
1
second_line = sites_preview[1]
-
1
expect(second_line).to eq([{:value=>"new val"}, {:value=>"invalid11"}, {:value=>"inval"}, {:value=>"Dad, inv"}, {:value=>"inval"},
-
{:value=>"999"}, {:value=>"12/26"}, {:value=>"non-existing@email.com"}, {:value=>"email@ma@il.com"}])
-
-
1
sites_errors = sites[:errors]
-
-
1
expect(sites_errors[:hierarchy_field_found]).to eq([{:new_hierarchy_columns=>[4]}])
-
1
expect(sites_errors[:duplicated_code]).to eq({})
-
1
expect(sites_errors[:duplicated_label]).to eq({})
-
1
expect(sites_errors[:existing_code]).to eq({})
-
1
expect(sites_errors[:existing_label]).to eq({})
-
-
1
data_errors = sites_errors[:data_errors]
-
1
expect(data_errors.length).to eq(5)
-
-
1
expect(data_errors[0][:description]).to eq("Some of the values in column 2 are not valid for the type numeric.")
-
1
expect(data_errors[0][:column]).to eq(1)
-
1
expect(data_errors[0][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[1][:description]).to eq("Some of the values in column 6 don't match any existing site id in this collection.")
-
1
expect(data_errors[1][:column]).to eq(5)
-
1
expect(data_errors[1][:rows]).to eq([1])
-
-
1
expect(data_errors[2][:description]).to eq("Some of the values in column 7 are not valid for the type date.")
-
1
expect(data_errors[2][:column]).to eq(6)
-
1
expect(data_errors[2][:rows]).to eq([1, 2])
-
-
1
expect(data_errors[3][:description]).to eq("Some of the values in column 8 don't match any email address of a member of this collection.")
-
1
expect(data_errors[3][:column]).to eq(7)
-
1
expect(data_errors[3][:rows]).to eq([1])
-
-
1
expect(data_errors[4][:description]).to eq("Some of the values in column 9 are not valid for the type email.")
-
1
expect(data_errors[4][:column]).to eq(8)
-
1
expect(data_errors[4][:rows]).to eq([1, 2])
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
-
1
it "should not create fields with duplicated name or code" do
-
1
layer.numeric_fields.make :code => 'new_field', :name => 'Existing field'
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['text']
-
1
csv << ['new val']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
1
column_spec = [
-
{header: 'Text', use_as: 'new_field', kind: 'text', code: 'text', label: 'Non Existing field'},
-
]
-
-
2
expect {ImportWizard.execute_with_entities(user, collection, column_spec)}.to raise_error(RuntimeError, "Can't save field from column Text: A field with code 'text' already exists in the layer named #{layer.name}")
-
-
1
column_spec = [
-
{header: 'Text', use_as: 'new_field', kind: 'text', code: 'newtext', label: 'Existing field'},
-
]
-
-
2
expect {ImportWizard.execute_with_entities(user, collection, column_spec)}.to raise_error(RuntimeError, "Can't save field from column Text: A field with label 'Existing field' already exists in the layer named #{layer.name}")
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
-
1
['lat', 'lng', 'name', 'id'].each do |usage|
-
4
it "should return validation errors when more than one column is selected to be #{usage}" do
-
4
csv_string = CSV.generate do |csv|
-
4
csv << ['col1', 'col2 ']
-
4
csv << ['val', 'val']
-
end
-
-
4
column_specs = [
-
{header: 'Column 1', use_as: "#{usage}"},
-
{header: 'Column 2', use_as:"#{usage}"}
-
]
-
-
4
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
4
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, column_specs)
-
-
4
sites_errors = sites_preview[:errors]
-
4
expect(sites_errors[:duplicated_usage]).to eq("#{usage}" => [0,1])
-
-
4
ImportWizard.delete_file(user, collection)
-
end
-
end
-
-
1
it "should return validation errors when more than one column is selected to be the same existing field" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['col1', 'col2 ']
-
1
csv << ['val', 'val']
-
end
-
-
1
column_specs = [
-
{header: 'Column 1', use_as: "existing_field", field_id: text.id},
-
{header: 'Column 2', use_as: "existing_field", field_id: text.id}
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, column_specs)
-
1
sites_errors = sites_preview[:errors]
-
1
expect(sites_errors[:duplicated_usage]).to eq(text.id => [0,1])
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
-
1
it "should not return duplicated_usage validation errror when there is more than one column with usage 'ignore'" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['col1', 'col2 ']
-
1
csv << ['val', 'val']
-
end
-
-
1
column_specs = [
-
{header: 'Column 1', use_as: "ignore"},
-
{header: 'Column 2', use_as: "ignore"}
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, column_specs)
-
-
1
sites_errors = sites_preview[:errors]
-
1
expect(sites_errors[:duplicated_usage]).to eq({})
-
-
1
ImportWizard.delete_file(user, collection)
-
-
end
-
-
1
['code', 'label'].each do |value|
-
2
it "should return validation errors when there is new_fields with duplicated #{value}" do
-
2
csv_string = CSV.generate do |csv|
-
2
csv << ['col1', 'col2 ']
-
2
csv << ['val', 'val']
-
end
-
-
2
column_specs = [
-
{header: 'Column 1', use_as: 'new_field', kind: 'select_one', "#{value}" => "repeated" },
-
{header: 'Column 2', use_as: 'new_field', kind: 'select_one', "#{value}" => "repeated" }
-
]
-
-
2
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
2
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, column_specs)
-
-
2
sites_errors = sites_preview[:errors]
-
2
key = "duplicated_#{value}".to_sym
-
2
expect(sites_errors[key]).to eq("repeated" => [0,1])
-
2
ImportWizard.delete_file(user, collection)
-
-
end
-
end
-
-
1
['code', 'label'].each do |value|
-
2
it "should return validation errors when there is existing_field with duplicated #{value}" do
-
2
if value == 'label'
-
1
repeated = layer.text_fields.make "name" => "repeated"
-
else
-
1
repeated = layer.text_fields.make "#{value}" => "repeated"
-
end
-
-
2
csv_string = CSV.generate do |csv|
-
2
csv << ['col1', 'col2 ']
-
2
csv << ['val', 'val']
-
end
-
-
2
column_specs = [
-
{header: 'Column 1', use_as: 'new_field', kind: 'select_one', "#{value}" => "repeated" },
-
{header: 'Column 2', use_as: 'new_field', kind: 'select_one', "#{value}" => "repeated" }
-
]
-
-
2
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
2
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, column_specs)
-
-
2
sites_errors = sites_preview[:errors]
-
2
key = "existing_#{value}".to_sym
-
2
expect(sites_errors[key]).to eq("repeated" => [0,1])
-
2
ImportWizard.delete_file(user, collection)
-
-
end
-
end
-
-
1
it "should not show errors if usage is ignore" do
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['numeric ']
-
1
csv << ['11']
-
1
csv << ['invalid11']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
-
1
columns_spec = [{header: 'numeric', use_as: 'ignore', kind: 'ignore'}]
-
1
validated_sites = (ImportWizard.validate_sites_with_columns user, collection, columns_spec)
-
-
1
sites_preview = validated_sites[:sites]
-
1
expect(sites_preview).to eq([[{:value=>"11"}], [{:value=>"invalid11"}]])
-
1
sites_errors = validated_sites[:errors]
-
-
1
expect(sites_errors[:data_errors]).to eq([])
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
1
it "should not generate a data error when updating a default property" do
-
1
site1 = collection.sites.make name: 'Foo old'
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name']
-
1
csv << ["#{site1.id}", 'Foo new']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: 'id', kind: 'id'},
-
{header: 'Name', use_as: 'name', kind: 'name'}]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
1
sites_errors = sites_preview[:errors]
-
1
expect(sites_errors[:data_errors]).to eq([])
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
# Otherwise a missmatch will be generated
-
1
it 'should not bypass columns with an empty value in the first row' do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['0', '' , '']
-
1
csv << ['1', '0', 'label2']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
-
1
expect(column_spec.length).to eq(3)
-
1
expect(column_spec[1][:header]).to eq("")
-
1
expect(column_spec[1][:code]).to eq("")
-
1
expect(column_spec[1][:label]).to eq("")
-
1
expect(column_spec[1][:use_as]).to eq(:new_field)
-
1
expect(column_spec[2][:header]).to eq("")
-
1
expect(column_spec[2][:code]).to eq("")
-
1
expect(column_spec[2][:label]).to eq("")
-
1
expect(column_spec[2][:use_as]).to eq(:new_field)
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
1
it 'should not fail if header has a nil value' do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['0', nil , nil]
-
1
csv << ['1', '0', 'label2']
-
end
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
-
1
expect(column_spec.length).to eq(3)
-
1
expect(column_spec[1][:header]).to eq("")
-
1
expect(column_spec[1][:code]).to eq("")
-
1
expect(column_spec[1][:label]).to eq("")
-
1
expect(column_spec[1][:use_as]).to eq(:new_field)
-
1
expect(column_spec[2][:header]).to eq("")
-
1
expect(column_spec[2][:code]).to eq("")
-
1
expect(column_spec[2][:label]).to eq("")
-
1
expect(column_spec[2][:use_as]).to eq(:new_field)
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
1
it 'should not fail if label and code are missing in new fields' do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['0', '' , '']
-
1
csv << ['1', '0', 'label2']
-
end
-
-
1
specs = [
-
{:header=>"0", :kind=>:numeric, :code=>"0", :label=>"0", :use_as=>:new_field},
-
{:header=>"", :kind=>:text, :code=>"", :label=>"", :use_as=>:new_field},
-
{:header=>"", :kind=>:text, :code=>"", :label=>"", :use_as=>:new_field}]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
1
sites_errors = sites_preview[:errors]
-
1
expect(sites_errors[:missing_label]).to eq(:columns => [1,2])
-
1
expect(sites_errors[:missing_code]).to eq(:columns => [1,2])
-
-
1
ImportWizard.delete_file(user, collection)
-
end
-
-
1
it "should validate presence of name in column specs" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['numeric']
-
1
csv << ['11']
-
end
-
-
1
specs = [{:header=>"numeric", :kind=>:numeric, :code=>"numeric", :label=>"numeric", :use_as=>:new_field}]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
1
sites_errors = sites_preview[:errors]
-
1
expect(sites_errors[:missing_name]).not_to be_blank
-
-
1
ImportWizard.delete_file(user, collection)
-
-
-
1
specs = [{:header=>"numeric", :use_as=>:name}]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
1
sites_errors = sites_preview[:errors]
-
1
expect(sites_errors[:missing_name]).to be_blank
-
-
1
ImportWizard.delete_file(user, collection)
-
-
end
-
-
1
Field.reserved_codes().each do |reserved_code|
-
5
it "should validate reserved code #{reserved_code} in new fields" do
-
5
csv_string = CSV.generate do |csv|
-
5
csv << ["#{reserved_code}"]
-
5
csv << ['11']
-
end
-
-
5
specs = [{:header=>"#{reserved_code}", :kind=>:text, :code=>"#{reserved_code}", :label=>"Label", :use_as=>:new_field}]
-
-
5
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
5
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
5
sites_errors = sites_preview[:errors]
-
5
expect(sites_errors[:reserved_code]).to eq({"#{reserved_code}"=>[0]})
-
5
ImportWizard.delete_file(user, collection)
-
-
end
-
end
-
-
1
it "should validate ids belong to collection's sites if a column is marked to be used as 'id'" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ["resmap-id"]
-
1
csv << ['']
-
1
csv << ['11']
-
end
-
-
1
specs = [{:header=>"resmap-id", :use_as=>:id}]
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
1
sites_errors = sites_preview[:errors]
-
-
1
expect(sites_errors[:non_existent_site_id].length).to eq(1)
-
1
resmap_id_error = sites_errors[:non_existent_site_id][0]
-
1
expect(resmap_id_error[:rows]).to eq([1])
-
1
expect(resmap_id_error[:column]).to eq(0)
-
1
ImportWizard.delete_file(user, collection)
-
-
end
-
-
1
it "should not show errors for valid sites ids(numeric or text)" do
-
1
site1 = collection.sites.make name: 'Bar'
-
1
site2 = collection.sites.make name: 'Foo'
-
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ["resmap-id"]
-
1
csv << ["#{site1.id}"]
-
1
csv << [site2.id]
-
end
-
-
1
specs = [{:header=>"resmap-id", :use_as=>:id}]
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string; ImportWizard.mark_job_as_pending user, collection
-
1
sites_preview = (ImportWizard.validate_sites_with_columns user, collection, specs)
-
1
sites_errors = sites_preview[:errors]
-
-
1
expect(sites_errors[:non_existent_site_id]).to be(nil)
-
1
ImportWizard.delete_file(user, collection)
-
-
end
-
-
1
it "shouldn't fail with blank lines at the end" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', 'Lat', 'Lon', 'Beds']
-
1
csv << ['Foo', '1.2', '3.4', '10']
-
1
csv << ['Bar', '5.6', '7.8', '20']
-
1
csv << []
-
1
csv << []
-
1
csv << []
-
end
-
-
1
specs = [
-
{header: 'Name', use_as: 'name'},
-
{header: 'Lat', use_as: 'lat'},
-
{header: 'Lon', use_as: 'lng'},
-
{header: 'Beds', use_as: 'new_field', kind: 'numeric', code: 'beds', label: 'The beds'},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string
-
1
ImportWizard.mark_job_as_pending user, collection
-
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
1
sites_errors = (ImportWizard.validate_sites_with_columns user, collection, column_spec)[:errors]
-
# do nothing (the test is that it shouldn't raise)
-
end
-
-
1
it "should not import files with invalid extension" do
-
1
File.open("example.txt", "w") do |f|
-
1
f.write("one, two")
-
end
-
2
expect { ImportWizard.import user, collection, 'example.txt', "one, two" }.to raise_error
-
end
-
-
1
it "should not import malformed csv files" do
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['Name', '2']
-
1
csv << ['Foo', '1.2', '3.4', '10']
-
end
-
2
expect { ImportWizard.import user, collection, 'foo.csv', csv_string }.to raise_error
-
end
-
-
1
it "should not fail when there is latin1 characters" do
-
1
csv_string = CSV.open("utf8.csv", "wb", encoding: "ISO-8859-1") do |csv|
-
1
csv << ["é", "ñ", "ç", "ø"]
-
1
csv << ["é", "ñ", "ç", "ø"]
-
end
-
-
1
specs = [
-
{header: 'é', use_as: 'name'},
-
{header: 'ñ', use_as: 'new_field', kind: 'text', code: 'text1', label: 'text 1'},
-
{header: 'ç', use_as: 'new_field', kind: 'text', code: 'text2', label: 'text 2'},
-
{header: 'ø', use_as: 'new_field', kind: 'text', code: 'text3', label: 'text 3'}
-
]
-
-
2
expect { ImportWizard.import user, collection, 'utf8.csv', csv_string }.to_not raise_error
-
2
expect { ImportWizard.mark_job_as_pending user, collection }.to_not raise_error
-
2
expect { column_spec = ImportWizard.guess_columns_spec user, collection}.to_not raise_error
-
1
column_spec = ImportWizard.guess_columns_spec user, collection
-
2
expect {ImportWizard.validate_sites_with_columns user, collection, column_spec}.to_not raise_error
-
end
-
-
1
describe 'updates' do
-
1
it 'only some fields of a valid site in a collection with one or more select one fields' do
-
# The collection has a valid site before the import
-
1
site1 = collection.sites.make name: 'Foo old', properties: {text.es_code => 'coco', select_one.es_code => 1}
-
-
# User uploads a CSV with only the resmap-id, name and text fields set.
-
# At the time of writing (1 Jul 2013), this causes the import to fail.
-
1
csv_string = CSV.generate do |csv|
-
1
csv << ['resmap-id', 'Name', text.name]
-
1
csv << [site1.id, 'Foo old', 'coco2']
-
end
-
-
1
specs = [
-
{header: 'resmap-id', use_as: :id},
-
{header: 'Name', use_as: 'name'},
-
{header: text.name , use_as: 'existing_field', field_id: text.id},
-
]
-
-
1
ImportWizard.import user, collection, 'foo.csv', csv_string
-
1
ImportWizard.mark_job_as_pending user, collection
-
-
1
ImportWizard.execute user, collection, specs
-
1
sites = collection.sites.reload
-
1
expect(sites.length).to eq(1)
-
-
1
expect(sites[0].name).to eq('Foo old')
-
1
expect(sites[0].properties[text.es_code]).to eq('coco2')
-
1
expect(sites[0].properties[select_one.es_code]).to eq(1)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
1
describe Site::IndexUtils do
-
2
let!(:user) { User.make }
-
2
let!(:collection) { user.create_collection Collection.make_unsaved }
-
2
let!(:site) {collection.sites.make :name => 'site_01'}
-
-
1
it 'should search site by site.id_with_prefix' do
-
1
search = collection.new_search
-
1
search.id site.id
-
1
expect(search.results.first['_source']["id_with_prefix"]).to eq site.id_with_prefix
-
end
-
end
-
-
1
require 'spec_helper'
-
-
1
describe "layer access" do
-
7
let!(:collection) { Collection.make }
-
7
let!(:user) { User.make }
-
7
let!(:membership) { Membership.create! user_id: user.id, collection_id: collection.id }
-
7
let!(:layer1) { collection.layers.make }
-
7
let!(:field1) { layer1.text_fields.make collection_id: collection.id }
-
7
let!(:layer2) { collection.layers.make }
-
7
let!(:field2) { layer2.text_fields.make collection_id: collection.id }
-
-
1
context "fields for user" do
-
1
it "only returns fields that can be read" do
-
1
membership.set_layer_access :verb => :read, :access => true, :layer_id => layer1.id
-
-
1
layers = collection.visible_layers_for user
-
1
expect(layers.length).to eq(1)
-
1
expect(layers[0][:name]).to eq(layer1.name)
-
-
1
fields = layers[0][:fields]
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0][:id]).to eq(field1.es_code)
-
1
expect(fields[0][:writeable]).to be_falsey
-
end
-
-
1
it "returns all fields if admin" do
-
1
membership.admin = true
-
1
membership.save!
-
-
1
layers = collection.visible_layers_for user
-
1
expect(layers.length).to eq(2)
-
1
expect(layers[0][:name]).to eq(layer1.name)
-
1
expect(layers[1][:name]).to eq(layer2.name)
-
-
1
fields = layers[0][:fields]
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0][:id]).to eq(field1.es_code)
-
1
expect(fields[0][:writeable]).to be_truthy
-
-
1
fields = layers[1][:fields]
-
1
expect(fields.length).to eq(1)
-
1
expect(fields[0][:id]).to eq(field2.es_code)
-
1
expect(fields[0][:writeable]).to be_truthy
-
end
-
end
-
-
1
context "can write field" do
-
1
it "can't write if property doesn't exist" do
-
1
expect(user.can_write_field?(nil, collection, "unexistent")).to be_falsey
-
end
-
-
1
it "can't write if only read access" do
-
1
membership.set_layer_access :verb => :read, :access => true, :layer_id => layer1.id
-
-
1
expect(user.can_write_field?(field1, collection, field1.es_code)).to be_falsey
-
end
-
-
1
it "can write if write access" do
-
1
membership.set_layer_access :verb => :write, :access => true, :layer_id => layer1.id
-
-
1
expect(user.can_write_field?(field1, collection, field1.es_code)).to be_truthy
-
end
-
-
1
it "can write if admin" do
-
1
membership.admin = true
-
1
membership.save!
-
-
1
expect(user.can_write_field?(field1, collection, field1.es_code)).to be_truthy
-
end
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe LayerMembership, :type => :model do
-
1
describe 'telemetry' do
-
7
let!(:user) { User.make }
-
7
let!(:collection) { Collection.make }
-
7
let!(:layer) { Layer.make collection: collection }
-
7
let!(:membership) { Membership.make collection: collection, user: user }
-
-
1
it 'should touch collection lifespan on create' do
-
1
layer_membership = LayerMembership.make_unsaved collection: collection, user: user
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
layer_membership.save
-
end
-
-
1
it 'should touch collection lifespan on update' do
-
1
layer_membership = LayerMembership.make collection: collection, user: user
-
1
layer_membership.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
layer_membership.save
-
end
-
-
1
it 'should touch collection lifespan on destroy' do
-
1
layer_membership = LayerMembership.make collection: collection, user: user
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
layer_membership.destroy
-
end
-
-
1
it 'should touch user lifespan on create' do
-
1
layer_membership = LayerMembership.make_unsaved collection: collection, user: user
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
layer_membership.save
-
end
-
-
1
it 'should touch user lifespan on update' do
-
1
layer_membership = LayerMembership.make collection: collection, user: user
-
1
layer_membership.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
layer_membership.save
-
end
-
-
1
it 'should touch user lifespan on destroy' do
-
1
layer_membership = LayerMembership.make collection: collection, user: user
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
layer_membership.destroy
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Layer do
-
2
it { is_expected.to belong_to :collection }
-
2
it { is_expected.to have_many :fields }
-
-
1
def history_concern_class
-
12
described_class
-
end
-
-
1
def history_concern_foreign_key
-
2
described_class.name.foreign_key
-
end
-
-
1
def history_concern_histories
-
1
"#{described_class}_histories"
-
end
-
-
1
it_behaves_like "it includes History::Concern"
-
end
-
1
require 'spec_helper'
-
-
1
describe MapSearch do
-
9
let(:collection) { Collection.make }
-
-
1
it "searches based on no collection" do
-
1
site = Site.make
-
-
1
search = MapSearch.new []
-
1
search.zoom = 1
-
1
expect(search.results).to eq({})
-
end
-
-
1
it "searches based on collection id found" do
-
1
site = Site.make
-
-
1
search = MapSearch.new site.collection_id
-
1
search.zoom = 1
-
-
1
expect(search.results[:sites].length).to be(1)
-
1
expected_hash = {collection_id: site.collection_id, id: site.id,
-
lat: site.lat.to_f, lng: site.lng.to_f,
-
name: site.name, id_with_prefix:"AA1",
-
lat_analyzed: site.lat.to_s, lng_analyzed: site.lng.to_s,
-
uuid: site.uuid, highlighted: false, icon: 'default', alert: 'false', version: "null"}
-
1
expect(search.results[:sites][0]).to eq(expected_hash)
-
end
-
-
1
it "searches with excluded id" do
-
1
site = Site.make
-
-
1
search = MapSearch.new site.collection_id
-
1
search.zoom = 1
-
1
search.exclude_id site.id
-
1
expect(search.results[:sites]).to be_nil
-
end
-
-
1
it "searches based on collection id not found" do
-
1
site = Site.make
-
1
other_collection = Collection.make
-
-
1
search = MapSearch.new other_collection.id
-
1
search.zoom = 1
-
1
expect(search.results[:sites]).to be_nil
-
end
-
-
1
it "searches based on many collection ids found" do
-
1
site1 = Site.make :lat => 45, :lng => 90
-
1
site2 = Site.make :lat => -45, :lng => -90
-
-
1
search = MapSearch.new [site1.collection_id, site2.collection_id]
-
1
search.zoom = 1
-
1
expect(search.results[:sites].length).to eq(2)
-
end
-
-
1
it "searches based on collection id and bounds found" do
-
1
site = Site.make :lat => 10, :lng => 20
-
-
1
search = MapSearch.new site.collection_id
-
1
search.zoom = 10
-
1
search.bounds = {:s => 9, :n => 11, :w => 19, :e => 21}
-
1
expect(search.results[:sites].length).to eq(1)
-
end
-
-
1
it "searches based on collection id and bounds not found" do
-
1
site = Site.make :lat => 10, :lng => 20
-
-
1
search = MapSearch.new site.collection_id
-
1
search.zoom = 10
-
1
search.bounds = {:s => 11, :n => 12, :w => 21, :e => 22}
-
1
expect(search.results[:sites]).to be_nil
-
end
-
-
1
it "searches but doesn't return sites without location" do
-
1
site = Site.make :lat => nil, :lng => nil
-
-
1
search = MapSearch.new site.collection_id
-
1
search.zoom = 1
-
1
search.bounds = {:s => 11, :n => 12, :w => 21, :e => 22}
-
1
expect(search.results[:sites]).to be_nil
-
end
-
-
1
context "full text search" do
-
9
let!(:layer) { collection.layers.make }
-
9
let!(:field_prop) { layer.select_one_fields.make :code => 'prop', :config => {'options' => [{'id' => 1, 'code' => 'foo', 'label' => 'A glass of water'}, {'id' => 2, 'code' => 'bar', 'label' => 'A bottle of wine'}, {'id' => 3, 'code' => 'baz', 'label' => 'COCO'}]} }
-
9
let!(:field_beds) { layer.numeric_fields.make :code => 'beds' }
-
9
let!(:prop) { field_prop.es_code }
-
9
let!(:beds) { field_beds.es_code }
-
9
let!(:site1) { collection.sites.make :name => "Argentina", :properties => {beds => 8, prop => 1} }
-
9
let!(:site2) { collection.sites.make :name => "Buenos Aires", :properties => {beds => 10, prop => 2} }
-
9
let!(:site3) { collection.sites.make :name => "Cordoba bar", :properties => {beds => 20, prop => 3} }
-
9
let!(:search) { MapSearch.new collection.id }
-
-
9
before(:each) { search.zoom = 1 }
-
-
1
it "searches by name" do
-
1
search.full_text_search 'Argent'
-
1
assert_result search, site1
-
end
-
-
1
it "searches by number property" do
-
1
search.full_text_search '8'
-
1
assert_result search, site1
-
end
-
-
1
it "searches by text property" do
-
1
search.full_text_search 'foo'
-
1
assert_result search, site1
-
end
-
-
1
it "searches by select one property" do
-
1
search.full_text_search 'water'
-
1
assert_result search, site1
-
end
-
-
1
it "doesn't give false positives" do
-
1
search.full_text_search 'wine'
-
1
assert_result search, site2
-
end
-
-
1
it "searches by name property" do
-
1
search.full_text_search('Buenos Aires')
-
1
assert_result search, site2
-
end
-
-
1
it "searches by numeric property" do
-
1
search.full_text_search('beds:8')
-
1
assert_result search, site1
-
end
-
-
1
it "searches by numeric property with comparison" do
-
1
search.full_text_search('beds:>10')
-
1
assert_result search, site3
-
end
-
-
1
def assert_result(search, site)
-
8
results = search.results
-
8
expect(results[:sites].length).to eq(1)
-
3
expect(results[:sites][0][:id]).to eq(site.id)
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Membership::LayerAccessConcern do
-
5
let(:collection) { Collection.make }
-
2
let(:user) { User.make }
-
2
let(:membership) { collection.memberships.create! :user_id => user.id }
-
5
let(:layer) { collection.layers.make }
-
-
1
context "layer access" do
-
4
let(:user2) { User.make }
-
4
let(:membership2) { collection.memberships.create! :user_id => user2.id }
-
-
1
context "when no access already exists" do
-
1
it "grants read access to layer" do
-
1
membership2.set_layer_access :verb => :read, :access => true, :layer_id => layer.id
-
1
lms = LayerMembership.all
-
1
expect(lms.length).to eq(1)
-
1
expect(lms[0].collection_id).to eq(collection.id)
-
1
expect(lms[0].layer_id).to eq(layer.id)
-
1
expect(lms[0].user_id).to eq(user2.id)
-
1
expect(lms[0].read).to be_truthy
-
1
expect(lms[0].write).to be_falsey
-
end
-
end
-
-
1
context "when access to layer already exists" do
-
1
it "grants read access and denies write access" do
-
1
LayerMembership.create! :collection_id => collection.id, :layer_id => layer.id, :user_id => user2.id, :read => false, :write => true
-
-
1
membership2.set_layer_access :verb => :read, :access => true, :layer_id => layer.id
-
-
1
lms = LayerMembership.all
-
1
expect(lms.length).to eq(1)
-
1
expect(lms[0].collection_id).to eq(collection.id)
-
1
expect(lms[0].layer_id).to eq(layer.id)
-
1
expect(lms[0].user_id).to eq(user2.id)
-
1
expect(lms[0].read).to be_truthy
-
1
expect(lms[0].write).to be_falsey
-
end
-
-
1
it "revokes read access" do
-
1
LayerMembership.create! :collection_id => collection.id, :layer_id => layer.id, :user_id => user2.id, :read => true, :write => false
-
-
1
membership2.set_layer_access :verb => :read, :access => false, :layer_id => layer.id
-
-
1
expect(LayerMembership.exists?).to be_falsey
-
end
-
end
-
end
-
-
1
context "on destroy" do
-
1
it "destroys collection layer memberships" do
-
-
1
collection.layer_memberships.create! :user_id => user.id, :layer_id => layer.id, :read => true, :write => true
-
-
1
membership.destroy
-
-
1
expect(collection.memberships.exists?).to be_falsey
-
1
expect(collection.layer_memberships.exists?).to be_falsey
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Membership::SitesPermissionConcern do
-
6
let!(:collection) { Collection.make }
-
6
let!(:user) { User.make }
-
6
let!(:membership) { collection.memberships.create! :user_id => user.id }
-
6
let!(:read_sites_permission) { membership.create_read_sites_permission all_sites: true, some_sites: [] }
-
-
1
it "should find sites permission" do
-
1
expect(membership.find_or_build_sites_permission(:read)).to eq read_sites_permission
-
end
-
-
1
it "should build sites permission" do
-
1
expect(membership.find_or_build_sites_permission(:write)).to be_new_record
-
end
-
-
1
describe "update sites permission" do
-
1
before(:each) do
-
3
membership.update_sites_permission({ read: {all_sites: false}, write: {all_sites: false, some_sites: [{id: 1, name: 'Bayon clinic'}]} })
-
end
-
-
1
it "should change read sites permission" do
-
1
expect(membership.read_sites_permission.all_sites).to eq false
-
end
-
-
1
it "should change write sites permission" do
-
1
permission = membership.write_sites_permission
-
-
1
expect(permission.all_sites).to eq false
-
1
expect(permission.some_sites.size).to eq(1)
-
1
expect(permission.some_sites[0]).to eq({id: 1, name: 'Bayon clinic'})
-
end
-
-
1
it "should accept post data from jquery" do
-
1
membership.update_sites_permission({read: {some_sites: {"0" => {"id" => "2", "name" => "Calmette hospital"}}}})
-
1
permission = membership.read_sites_permission
-
-
1
expect(permission.some_sites.size).to eq(1)
-
1
expect(permission.some_sites[0]).to eq({"id" => "2", "name" => "Calmette hospital"})
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Membership do
-
2
it { is_expected.to belong_to :user }
-
2
it { is_expected.to belong_to :collection }
-
2
it { is_expected.to have_one :read_sites_permission }
-
2
it { is_expected.to have_one :write_sites_permission }
-
-
6
let(:collection) { Collection.make }
-
6
let(:user) { User.make }
-
5
let(:membership) { collection.memberships.create! :user_id => user.id }
-
1
let(:layer) { collection.layers.make }
-
-
1
describe "sites permission" do
-
1
it "should include read permission" do
-
1
read_permission = membership.create_read_sites_permission all_sites: true
-
1
expect(membership.sites_permission).to include(read: read_permission)
-
end
-
-
1
it "should include write permission" do
-
1
write_permission = membership.create_write_sites_permission all_sites: true
-
1
expect(membership.sites_permission).to include(write: write_permission)
-
end
-
-
1
it "should not allow more than one membership per collection and user" do
-
1
user.memberships.create! :collection_id => collection.id
-
2
expect { user.memberships.create!(:collection_id => collection.id) }.to raise_error
-
end
-
-
1
context "when user is collection admin" do
-
1
it "should allow read for all sites" do
-
1
membership.admin = true
-
1
expect(membership.sites_permission[:read].all_sites).to be true
-
end
-
-
1
it "should allow write for all sites" do
-
1
membership.admin = true
-
1
expect(membership.sites_permission[:write].all_sites).to be true
-
end
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
# For single rspec test run file you need to require below file
-
# require 'polyglot'
-
# require File.expand_path(File.join(Rails.root, '/spec/lib/treetop/treetop_helper'))
-
-
# Treetop.load File.expand_path(File.join(Rails.root, '/lib/treetop/command'))
-
-
1
describe Message do
-
1
context "new" do
-
6
subject { Message.new }
-
-
2
it { is_expected.to be_invalid }
-
2
it { is_expected.to validate_presence_of(:guid) }
-
2
it { is_expected.to validate_presence_of(:body) }
-
2
it { is_expected.to validate_presence_of(:from) }
-
2
it { expect(subject.save).to be_falsy }
-
# its(:save) { should be_false }
-
end
-
-
1
describe "check message channel and sender" do
-
1
before(:each) do
-
4
@message = Message.new
-
end
-
-
1
it "should not be an sms" do
-
1
expect(@message).not_to be_channel(:sms)
-
end
-
-
1
it "should not have a sender" do
-
1
expect(@message.sender).to be_nil
-
end
-
-
1
it "should check message is and sms" do
-
1
@message.from = "sms://1"
-
1
expect(@message).to be_channel(:sms)
-
end
-
-
1
it "should find sender by phone number" do
-
1
user = User.make :phone_number => "1"
-
1
@message.from = "sms://1"
-
1
expect(@message.sender).to eq(user)
-
end
-
end
-
-
1
describe "#process!" do
-
1
before(:each) do
-
2
collection = Collection.make
-
2
user = User.make :phone_number => '123'
-
2
collection.memberships.create :user => user, :admin => true
-
2
body = "dyrm q #{collection.id} beds>12"
-
2
@message = Message.new :guid => '999', :from => 'sms://123', :body => body
-
end
-
-
1
it "should save reply" do
-
1
expect(@message).to receive(:visit).and_return("done")
-
1
@message.process!
-
1
expect(@message.reply).to eq("done")
-
end
-
-
1
context "when command is invalid" do
-
1
before(:each) do
-
1
@message.body = "dyrm foo"
-
1
@message.save
-
end
-
-
1
it "should not save reply" do
-
2
expect { @message.process! }.to raise_error(RuntimeError, "Invalid command")
-
1
expect(@message.reply).to be_nil
-
end
-
end
-
end
-
-
1
describe "visit command" do
-
1
it "should accept ExecVisitor" do
-
1
message = Message.create :guid => '999', :from => 'sms://123', :body => "foo"
-
1
command = double('Command')
-
1
expect(command).to receive(:sender=)
-
1
expect(command).to receive(:accept)
-
# Execute
-
1
message.visit command, nil
-
end
-
end
-
-
1
describe "message log" do
-
3
let(:collection) { Collection.make quota: 10 }
-
1
it 'should change collection.quota after log message' do
-
1
expect{
-
1
Message.log [{from: '123456', to: '123456', body: 'hello resourcemap'}], collection.id
-
}.to change{
-
2
c = Collection.find collection.id
-
2
c.quota
-
}.from(10).to(9)
-
end
-
-
-
1
it "shouldn't change collection.quota after create new message with property is_send == false" do
-
1
message = Message.new from: '123456', to: '123456', body: 'hello resourcemap', is_send: false, collection_id: collection.id
-
1
c = Collection.find collection.id
-
1
expect(c.quota).to eq collection.quota
-
end
-
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Object do
-
1
it "converts to_i with to_i_or_f" do
-
1
expect("123".to_i_or_f).to eq(123)
-
end
-
-
1
it "converts to_f with to_i_or_f" do
-
1
expect("123.4".to_i_or_f).to eq(123.4)
-
end
-
-
1
it "converts to nil with to_i_or_f" do
-
1
expect("Hello".to_i_or_f).to be_nil
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Prefix do
-
1
it "should get first next prefix" do
-
1
expect(Prefix.next.version).to eq("AA")
-
end
-
-
1
it "should get next prefix" do
-
1
Prefix.create :version => 'AX'
-
1
expect(Prefix.next.version).to eq('AY')
-
end
-
-
1
it "should save prefix after get next prefix" do
-
1
expect {
-
1
Prefix.next
-
2
}.to change { Prefix.count }.by(1)
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe SearchParser do
-
1
it "nil" do
-
1
s = SearchParser.new(nil)
-
1
assert_equal nil, s.search
-
end
-
-
1
it "simple 1" do
-
1
s = SearchParser.new('search')
-
1
expect(s.search).to eq('search')
-
end
-
-
1
it "simple 2" do
-
1
s = SearchParser.new('hello world')
-
1
expect(s.search).to eq('hello world')
-
end
-
-
1
it "key value" do
-
1
s = SearchParser.new('key:value')
-
1
expect(s.search).to be_nil
-
1
expect(s['key']).to eq('value')
-
end
-
-
1
it "key value with words" do
-
1
s = SearchParser.new('one key:value other:thing two')
-
1
expect(s.search).to eq('one two')
-
1
expect(s['key']).to eq('value')
-
1
expect(s['other']).to eq('thing')
-
end
-
-
1
it "key value with quotes" do
-
1
s = SearchParser.new('key:"more than one word"')
-
1
expect(s.search).to be_nil
-
1
expect(s['key']).to eq('more than one word')
-
end
-
-
1
it "key value with quotes twice" do
-
1
s = SearchParser.new('key:"more than one word" key2:"something else"')
-
1
expect(s.search).to be_nil
-
1
expect(s['key']).to eq('more than one word')
-
1
expect(s['key2']).to eq('something else')
-
end
-
-
1
it "key value with quotes and symbols" do
-
1
s = SearchParser.new('key:"more than : one word"')
-
1
expect(s.search).to be_nil
-
1
expect(s['key']).to eq('more than : one word')
-
end
-
-
1
it "key value with colon" do
-
1
s = SearchParser.new('key:something:else')
-
1
expect(s.search).to be_nil
-
1
expect(s['key']).to eq('something:else')
-
end
-
-
1
it "key value with protocol" do
-
1
s = SearchParser.new('key:value://hola')
-
1
expect(s.search).to be_nil
-
1
expect(s['key']).to eq('value://hola')
-
end
-
-
1
it "quotes" do
-
1
s = SearchParser.new('"more than one word"')
-
1
expect(s.search).to eq('"more than one word"')
-
end
-
-
1
it "semicolon" do
-
1
s = SearchParser.new(';')
-
1
expect(s.search).to eq(';')
-
end
-
-
1
it "parses location coordinate without hyphen" do
-
1
s = SearchParser.new('32.123')
-
1
expect(s.search).to eq('32.123')
-
end
-
-
1
it "parses location coordinate with hyphen" do
-
1
s = SearchParser.new('-32.123')
-
1
expect(s.search).to eq('32.123')
-
end
-
-
1
it "parses word hyphen word" do
-
1
s = SearchParser.new('my-site')
-
1
expect(s.search).to eq('my - site')
-
end
-
-
1
it "parses word dot number" do
-
1
s = SearchParser.new('MySite.32')
-
1
expect(s.search).to eq('MySite . 32')
-
end
-
-
1
it "parses number dot word" do
-
1
s = SearchParser.new('32.MySite')
-
1
expect(s.search).to eq('32 . MySite')
-
end
-
-
1
it "parses decimal number space word" do
-
1
s = SearchParser.new('32.3 foo')
-
1
expect(s.search).to eq('32.3 foo')
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Search do
-
82
let!(:user) { User.make }
-
82
let!(:collection) { user.create_collection(Collection.make) }
-
72
let!(:layer) { collection.layers.make }
-
-
1
context "search by property" do
-
25
let!(:beds) { layer.numeric_fields.make code: 'beds' }
-
25
let!(:tables) { layer.numeric_fields.make code: 'tables' }
-
25
let!(:first_name) { layer.text_fields.make code: 'first_name' }
-
25
let!(:country) { layer.text_fields.make code: 'country' }
-
25
let!(:hierarchy) { layer.hierarchy_fields.make code: 'hie', config: { "hierarchy" => [{ 'id' => 1, 'name' => 'root'}] } }
-
-
-
25
let!(:site1) { collection.sites.make properties:
-
{beds.es_code => 5, tables.es_code => 1, first_name.es_code => "peterin panini", country.es_code => "argentina"} }
-
25
let!(:site2) { collection.sites.make properties:
-
{beds.es_code => 10, tables.es_code => 2, first_name.es_code => "peter pan", country.es_code => "albania"} }
-
25
let!(:site3) { collection.sites.make properties:
-
{beds.es_code => 20, tables.es_code => 3, first_name.es_code => "Alice Cooper", country.es_code => "argelia", hierarchy.es_code => 1} }
-
25
let!(:site4) { collection.sites.make properties:
-
{beds.es_code => 10, tables.es_code => 4, first_name.es_code => "John Doyle", country.es_code => "south arabia", hierarchy.es_code => 1} }
-
-
1
it "searches by equality" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => 10
-
1
assert_results search, site2, site4
-
end
-
-
1
it "searches by equality with code" do
-
1
search = collection.new_search
-
1
search.use_codes_instead_of_es_codes
-
1
search.where 'beds' => 10
-
1
assert_results search, site2, site4
-
end
-
-
1
it "searches by equality with @code" do
-
1
search = collection.new_search
-
1
search.use_codes_instead_of_es_codes
-
1
search.where '@beds' => 10
-
1
assert_results search, site2, site4
-
end
-
-
1
it "searches by equality on hierarchy field" do
-
1
search = collection.new_search
-
1
search.where hierarchy.es_code => [1]
-
1
assert_results search, site3, site4
-
end
-
-
1
it "searches by equality of two properties" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => 10, tables.es_code => 2
-
1
assert_results search, site2
-
end
-
-
1
it "searches by equality of two properties but doesn't find" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => 10, tables.es_code => 1
-
1
expect(search.results.length).to eq(0)
-
end
-
-
1
it "searches by starts with" do
-
1
search = collection.new_search
-
1
search.where first_name.es_code => "~=peter"
-
1
assert_results search, site1, site2
-
end
-
-
1
it "searches by starts with and equality" do
-
1
search = collection.new_search
-
1
search.where first_name.es_code => "~=peter"
-
1
search.where beds.es_code => 5
-
1
assert_results search, site1
-
end
-
-
1
it "searches by starts with on two different fields" do
-
1
search = collection.new_search
-
1
search.where first_name.es_code => "~=peter"
-
1
search.where country.es_code => "~=arg"
-
1
assert_results search, site1
-
end
-
-
1
it "searches by two comparisons on the same field" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => "<=20"
-
1
search.where beds.es_code => ">7"
-
1
assert_results search, site2, site3, site4
-
end
-
-
1
context "full text search" do
-
3
let!(:population_source) { layer.text_fields.make :code => 'population_source' }
-
-
1
it "searches by equality with text" do
-
1
a_site = collection.sites.make :properties => {population_source.es_code => "National Census"}
-
1
search = collection.new_search
-
1
search.where population_source.es_code => "National Census"
-
1
assert_results search, a_site
-
end
-
-
1
it "searches by equality with text doesn't confuse name" do
-
1
a_site = collection.sites.make :name => "Census", :properties => {population_source.es_code => "National"}
-
1
search = collection.new_search
-
1
search.where population_source.es_code => "National Census"
-
1
expect(search.results.length).to eq(0)
-
end
-
end
-
-
1
it "searches with lt" do
-
1
search = collection.new_search
-
1
search.lt beds, 8
-
1
assert_results search, site1
-
end
-
-
1
it "searches with lte" do
-
1
search = collection.new_search
-
1
search.lte beds, 10
-
1
assert_results search, site1, site2, site4
-
end
-
-
1
it "searches with gt" do
-
1
search = collection.new_search
-
1
search.gt beds, 18
-
1
assert_results search, site3
-
end
-
-
1
it "searches with gte" do
-
1
search = collection.new_search
-
1
search.gte beds, 10
-
1
assert_results search, site2, site3, site4
-
end
-
-
1
it "searches with combined properties" do
-
1
search = collection.new_search
-
1
search.lt beds, 11
-
1
search.gte tables, 4
-
1
assert_results search, site4
-
end
-
-
1
it "searches with ops" do
-
1
search = collection.new_search
-
1
search.op beds, '<', 8
-
1
search.op tables, '>=', 1
-
1
assert_results search, site1
-
end
-
-
1
context "where with op" do
-
1
it "searches where with lt" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => '< 8'
-
1
assert_results search, site1
-
end
-
-
1
it "searches where with lte" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => '<= 5'
-
1
assert_results search, site1
-
end
-
-
1
it "searches where with gt" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => '> 19'
-
1
assert_results search, site3
-
end
-
-
1
it "searches where with gte" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => '>= 20'
-
1
assert_results search, site3
-
end
-
-
1
it "searches where with eq" do
-
1
search = collection.new_search
-
1
search.where beds.es_code => '= 10'
-
1
assert_results search, site2, site4
-
end
-
end
-
-
1
context "unknow field" do
-
1
it "raises on unknown field" do
-
1
search = collection.new_search
-
2
expect { search.where '0' => 10 }.to raise_error(RuntimeError, "Unknown field: 0")
-
end
-
end
-
end
-
-
1
context "find by id" do
-
2
let!(:site1) { collection.sites.make }
-
2
let!(:site2) { collection.sites.make }
-
-
1
it "finds by id" do
-
1
assert_results collection.new_search.id(site1.id), site1
-
end
-
end
-
-
1
context "pagination" do
-
1
it "paginates by 50 results by default" do
-
1
search = collection.new_search
-
1
expect(search.page_size).to eq(50)
-
end
-
-
1
context "with another page size" do
-
3
let!(:search) { collection.new_search}
-
1
before(:each) do
-
2
@original_page_size = search.page_size
-
2
search.page_size = 2
-
end
-
-
1
after(:each) do
-
2
search.page_size = @original_page_size
-
end
-
-
1
it "gets first page" do
-
4
sites = 3.times.map { collection.sites.make }
-
3
sites.sort! { |s1, s2| s1.name <=> s2.name }
-
1
assert_results search, sites[0], sites[1]
-
end
-
-
1
it "gets second page" do
-
4
sites = 3.times.map { collection.sites.make }
-
3
sites.sort! { |s1, s2| s1.name <=> s2.name }
-
1
assert_results search.page(2), sites[2]
-
end
-
end
-
end
-
-
1
context "after" do
-
1
before(:each) do
-
4
@site1 = collection.sites.make :updated_at => (Time.now - 3.days)
-
4
@site2 = collection.sites.make :updated_at => (Time.now - 2.days)
-
4
@site3 = collection.sites.make :updated_at => (Time.now - 1.days)
-
end
-
-
1
it "gets results before a date" do
-
1
assert_results collection.new_search.before(@site2.updated_at + 1.second), @site1, @site2
-
end
-
-
1
it "gets results before a date as string" do
-
1
assert_results collection.new_search.before((@site2.updated_at + 1.second).to_s), @site1, @site2
-
end
-
-
1
it "gets results after a date" do
-
1
assert_results collection.new_search.after(@site2.updated_at - 1.second), @site2, @site3
-
end
-
-
1
it "gets results after a date as string" do
-
1
assert_results collection.new_search.after((@site2.updated_at - 1.second).to_s), @site2, @site3
-
end
-
end
-
-
1
context "full text search" do
-
11
let!(:layer) { collection.layers.make }
-
11
let!(:prop) { layer.select_one_fields.make :code => 'prop', :config => {'options' => [{'id' => 1, 'code' => 'foo', 'label' => 'A glass of water'}, {'id' => 2, 'code' => 'bar', 'label' => 'A bottle of wine'}, {'id' => 3, 'code' => 'baz', 'label' => 'COCO'}]} }
-
11
let!(:beds) { layer.numeric_fields.make :code => 'beds' }
-
11
let!(:site1) { collection.sites.make :name => "Argentina", :properties => {beds.es_code => 8, prop.es_code => 1} }
-
11
let!(:site2) { collection.sites.make :name => "Buenos Aires", :properties => {beds.es_code => 10, prop.es_code => 2} }
-
11
let!(:site3) { collection.sites.make :name => "Cordoba bar Buenos", :properties => {beds.es_code => 20, prop.es_code => 3} }
-
11
let!(:search) { collection.new_search }
-
-
1
it "finds by name" do
-
1
assert_results collection.new_search.full_text_search("Argent"), site1
-
1
assert_results collection.new_search.full_text_search("Buenos"), site2, site3
-
end
-
-
1
it "finds by number property" do
-
1
assert_results collection.new_search.full_text_search(8), site1
-
end
-
-
1
it "finds by text property" do
-
1
assert_results collection.new_search.full_text_search("foo"), site1
-
end
-
-
1
it "finds by value of select one property" do
-
1
assert_results collection.new_search.full_text_search("water"), site1
-
end
-
-
1
it "finds by value of select one property using where" do
-
1
search.use_codes_instead_of_es_codes
-
1
assert_results search.where(prop.code => "A glass of water"), site1
-
end
-
-
1
it "doesn't give false positives" do
-
1
assert_results search.full_text_search("wine"), site2
-
end
-
-
1
it "searches whole phrase, not part of it" do
-
1
assert_results search.full_text_search("Buenos Aires"), site2
-
end
-
-
1
it "searches by numeric property" do
-
1
assert_results search.full_text_search('beds:8'), site1
-
end
-
-
1
it "searches by numeric property with comparison" do
-
1
assert_results search.full_text_search('beds:>=10'), site2, site3
-
end
-
-
1
it "searches by label value" do
-
1
assert_results search.full_text_search("prop:water"), site1
-
end
-
end
-
-
1
context "geo" do
-
8
let!(:site1) { collection.sites.make lat: 10, lng: 20}
-
8
let!(:site2) { collection.sites.make lat: 15.321, lng: 25.123}
-
8
let!(:site3) { collection.sites.make lat: 40, lng: -60.1}
-
-
1
it "searches by box" do
-
1
assert_results collection.new_search.box(19, 9, 26, 16), site1, site2
-
end
-
-
1
it "searches by text km radius" do
-
1
assert_results collection.new_search.radius(12.5, 22.5, '600km'), site1, site2
-
end
-
-
1
it "searches by text miles radius" do
-
1
assert_results collection.new_search.radius(12.5, 22.5, '434mi'), site1, site2
-
end
-
-
1
it "searches by numeric radius" do
-
1
assert_results collection.new_search.radius(12.5, 22.5, 600000), site1, site2
-
end
-
-
1
it "searches by numeric radius on single site" do
-
1
assert_results collection.new_search.radius(10, 20, 1), site1
-
end
-
-
1
it "full text searches by lat" do
-
1
assert_results collection.new_search.full_text_search("15.3"), site2
-
1
assert_results collection.new_search.full_text_search("-60.1"), site3
-
end
-
-
1
it "full text searches by lng" do
-
1
assert_results collection.new_search.full_text_search("25.1"), site2
-
end
-
end
-
-
1
context "results format" do
-
7
let!(:text) { layer.text_fields.make :code => 'text' }
-
7
let!(:numeric) { layer.numeric_fields.make :code => 'numeric' }
-
7
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
7
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
-
7
let!(:site1) { collection.sites.make :lat => 1, :lng => 2, :properties => {text.es_code => 'foo', numeric.es_code => 1, select_one.es_code => 1, select_many.es_code => [1, 2]} }
-
-
1
it "gets results" do
-
1
result = collection.new_search.results[0]
-
1
expect(result['_source']['properties'][text.es_code]).to eq('foo')
-
1
expect(result['_source']['properties'][numeric.es_code]).to eq(1)
-
1
expect(result['_source']['properties'][select_one.es_code]).to eq(1)
-
1
expect(result['_source']['properties'][select_many.es_code]).to eq([1, 2])
-
end
-
-
1
it "gets api results" do
-
1
search = collection.new_search current_user_id: user.id
-
1
result = search.api_results[0]
-
1
expect(result['_source']['properties'][text.code]).to eq('foo')
-
1
expect(result['_source']['properties'][numeric.code]).to eq(1)
-
1
expect(result['_source']['properties'][select_one.code]).to eq('one')
-
1
expect(result['_source']['properties'][select_many.code]).to eq(['one', 'two'])
-
end
-
-
-
1
it "gets api results from snapshot" do
-
1
snapshot = collection.snapshots.create! date: Time.now, name: 'snp1'
-
1
snapshot.user_snapshots.create! user: user
-
-
1
site1.properties = {text.es_code => 'foo2', numeric.es_code => 2, select_one.es_code => 2, select_many.es_code => [2]}
-
1
site1.save!
-
-
1
search = collection.new_search current_user_id: user.id
-
1
result = search.api_results[0]
-
1
expect(result['_source']['properties'][text.code]).to eq('foo2')
-
1
expect(result['_source']['properties'][numeric.code]).to eq(2)
-
1
expect(result['_source']['properties'][select_one.code]).to eq('two')
-
1
expect(result['_source']['properties'][select_many.code]).to eq(['two'])
-
-
1
search = collection.new_search current_user_id: user.id, snapshot_id: snapshot.id
-
1
result = search.api_results[0]
-
1
expect(result['_source']['properties'][text.code]).to eq('foo')
-
expect(result['_source']['properties'][numeric.code]).to eq(1)
-
expect(result['_source']['properties'][select_one.code]).to eq('one')
-
expect(result['_source']['properties'][select_many.code]).to eq(['one', 'two'])
-
end
-
-
1
it "gets ui results" do
-
1
search = collection.new_search current_user_id: user.id
-
1
result = search.ui_results[0]
-
1
expect(result['_source']['lat']).to eq(1)
-
1
expect(result['_source']['lng']).to eq(2)
-
end
-
-
1
it "gets ui form snapshot" do
-
1
snapshot = collection.snapshots.create! date: Time.now, name: 'snp1'
-
1
snapshot.user_snapshots.create! user: user
-
-
1
site1.properties = {text.es_code => 'foo2', numeric.es_code => 2, select_one.es_code => 2, select_many.es_code => [2]}
-
1
site1.save!
-
-
1
search = collection.new_search current_user_id: user.id
-
1
result = search.ui_results[0]
-
-
1
expect(result['_source']['properties'][text.es_code]).to eq('foo2')
-
1
expect(result['_source']['properties'][numeric.es_code]).to eq(2)
-
1
expect(result['_source']['properties'][select_one.es_code]).to eq(2)
-
1
expect(result['_source']['properties'][select_many.es_code]).to eq([2])
-
-
1
search = collection.new_search current_user_id: user.id, snapshot_id: snapshot.id
-
1
result = search.ui_results[0]
-
1
expect(result['_source']['properties'][text.es_code]).to eq('foo')
-
expect(result['_source']['properties'][numeric.es_code]).to eq(1)
-
expect(result['_source']['properties'][select_one.es_code]).to eq(1)
-
expect(result['_source']['properties'][select_many.es_code]).to eq([1, 2])
-
end
-
-
1
it "do not get deleted fields" do
-
1
numeric.delete
-
1
search = collection.new_search current_user_id: user.id
-
1
result = search.ui_results[0]
-
1
expect(result['_source']['properties'][numeric.es_code]).to be_nil
-
end
-
-
end
-
-
1
context "sort" do
-
7
let!(:numeric) { layer.numeric_fields.make :code => 'numeric' }
-
-
7
let!(:site1) { collection.sites.make :name => 'Brian Adams', :properties => {numeric.es_code => 2} }
-
7
let!(:site2) { collection.sites.make :name => 'Esther Goris', :properties => {numeric.es_code => 1} }
-
-
7
let!(:search) { collection.new_search.use_codes_instead_of_es_codes }
-
-
1
it "sorts on name asc by default" do
-
1
result = search.results
-
3
expect(result.map { |x| x['_id'].to_i }) .to eq([site1.id, site2.id])
-
end
-
-
1
it "sorts by field asc" do
-
1
result = search.sort(numeric.code).results
-
expect(result.map { |x| x['_id'].to_i }) .to eq([site2.id, site1.id])
-
end
-
-
1
it "sorts by field desc" do
-
1
result = search.sort(numeric.code, false).results
-
expect(result.map { |x| x['_id'].to_i }) .to eq([site1.id, site2.id])
-
end
-
-
1
it "sorts by name asc" do
-
1
result = search.sort('name').results
-
3
expect(result.map { |x| x['_id'].to_i }) .to eq([site1.id, site2.id])
-
end
-
-
1
it "sorts by name desc" do
-
1
result = search.sort('name', false).results
-
3
expect(result.map { |x| x['_id'].to_i }) .to eq([site2.id, site1.id])
-
end
-
-
1
it "sorts by multiple fields" do
-
1
site3 = collection.sites.make :name => 'Esther Goris', :properties => {numeric.es_code => 2}
-
1
result = search.sort_multiple({'name' => true, numeric.code => false}).results
-
expect(result.map { |x| x['_id'].to_i }) .to eq([site1.id, site3.id, site2.id])
-
end
-
end
-
-
1
context "location missing" do
-
2
let!(:site1) { collection.sites.make :name => 'b', :lat => "", :lng => "" }
-
2
let!(:site2) { collection.sites.make :name => 'a' }
-
-
1
it "should filter sites without location" do
-
1
result = collection.new_search.location_missing.results
-
2
expect(result.map { |x| x['_id'].to_i }) .to eq([site1.id])
-
end
-
-
end
-
-
1
context "filter by date field range" do
-
6
let!(:creation) { layer.date_fields.make code: 'creation' }
-
6
let!(:inaguration) { layer.date_fields.make code: 'inaguration' }
-
-
6
let!(:site1) { collection.sites.make :name => 'b', properties: { creation.es_code =>"2012-09-07T00:00:00Z", inaguration.es_code =>"2012-09-23T00:00:00Z"} }
-
6
let!(:site2) { collection.sites.make :name => 'a', properties: { creation.es_code =>"2013-09-07T00:00:00Z", inaguration.es_code =>"2012-09-23T00:00:00Z"} }
-
-
1
it "should parse date from" do
-
1
search = collection.new_search
-
1
parameter = "12/12/2012,1/1/2013"
-
1
date = creation.send(:parse_date_from, parameter)
-
1
expect(date).to eq("12/12/2012")
-
end
-
-
1
it "should parse date to" do
-
1
search = collection.new_search
-
1
parameter = "12/12/2012,1/1/2013"
-
1
date = creation.send(:parse_date_to, parameter)
-
1
expect(date).to eq("1/1/2013")
-
end
-
-
1
it "should search by range" do
-
1
search = collection.new_search
-
1
search.where creation.es_code => "=09/06/2012,09/08/2012"
-
1
assert_results search, site1
-
end
-
-
1
it "should search by specific date" do
-
1
search = collection.new_search
-
1
search.where inaguration.es_code => "=09/23/2012,09/23/2012"
-
1
assert_results search, site1, site2
-
end
-
-
1
it "searches by date with @code" do
-
1
search = collection.new_search
-
1
search.use_codes_instead_of_es_codes
-
1
search.where creation.code => "=09/06/2012,09/08/2012"
-
1
assert_results search, site1
-
end
-
-
-
-
end
-
-
1
context 'filter by hierarchy' do
-
7
let!(:unit) { layer.hierarchy_fields.make code: 'unit', 'config' => {'hierarchy' => [{'id' => 1, 'name' => 'Buenos Aires', 'sub' => [{ 'id' => 2, 'name' => 'Vicente Lopez'}]}, {'id' => 3, 'name' => 'Formosa'}]} }
-
7
let!(:first_name) { layer.text_fields.make code: 'first_name'}
-
-
7
let!(:site1) { collection.sites.make properties:
-
{ first_name.es_code => "At Buenos Aires", unit.es_code => 1 } }
-
7
let!(:site2) { collection.sites.make properties:
-
{ first_name.es_code => "At Vicente Lopez", unit.es_code => 2 } }
-
7
let!(:site3) { collection.sites.make properties:
-
{ first_name.es_code => "At Vicente Lopez 2", unit.es_code => 2 } }
-
7
let!(:site4) { collection.sites.make properties:
-
{ first_name.es_code => "At Formosa", unit.es_code => 3 } }
-
7
let!(:site5) { collection.sites.make properties:
-
{ first_name.es_code => "Nowhere" } }
-
7
let!(:search) { collection.new_search }
-
-
1
it 'should filter sites inside some specified item by id' do
-
1
search.where unit.es_code => { under: 1 }
-
1
assert_results search, site1, site2, site3
-
end
-
-
1
it 'should filter sites inside some specified item by id again' do
-
1
search.where unit.es_code => { under: 3 }
-
1
assert_results search, site4
-
end
-
-
1
it 'should filter sites inside some specified item by name' do
-
1
search.use_codes_instead_of_es_codes
-
1
search.where unit.code => { under: 'Buenos Aires' }
-
1
assert_results search, site1, site2, site3
-
end
-
-
1
it "searches by hierarchy with @code" do
-
1
search.use_codes_instead_of_es_codes
-
1
search.where unit.code => ['Buenos Aires']
-
1
assert_results search, site1
-
end
-
-
1
it "searches by multiple hierarchy with @code" do
-
1
search.use_codes_instead_of_es_codes
-
1
search.where unit.code => ['Buenos Aires', 'Vicente Lopez']
-
1
assert_results search, site1, site2, site3
-
end
-
-
1
it "searches by multiple hierarchy with @es_code" do
-
1
search.where unit.es_code => [1, 2]
-
1
assert_results search, site1, site2, site3
-
end
-
end
-
-
1
context 'filter by yes_no' do
-
3
let!(:cool) { layer.yes_no_fields.make code: 'cool'}
-
-
3
let!(:site1) { collection.sites.make properties: { cool.es_code => true } }
-
3
let!(:site2) { collection.sites.make properties: { cool.es_code => false } }
-
-
1
it "should filter by 'yes'" do
-
1
search = collection.new_search
-
1
search.where cool.es_code => 'yes'
-
1
assert_results search, site1
-
end
-
-
1
it "should filter by 'no'" do
-
1
search = collection.new_search
-
1
search.where cool.es_code => 'no'
-
1
assert_results search, site2
-
end
-
end
-
-
1
context 'hierarchy parameter for select_kind and hierarchy fields' do
-
7
let!(:select_one) { layer.select_one_fields.make :code => 'select_one', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
7
let!(:select_many) { layer.select_many_fields.make :code => 'select_many', :config => {'options' => [{'id' => 1, 'code' => 'one', 'label' => 'One'}, {'id' => 2, 'code' => 'two', 'label' => 'Two'}]} }
-
1
config_hierarchy = [{ id: '60', name: 'Dad', sub: [{id: '100', name: 'Son'}, {id: '101', name: 'Bro'}]}]
-
7
let!(:hierarchy) { layer.hierarchy_fields.make :code => 'hierarchy', config: { hierarchy: config_hierarchy }.with_indifferent_access }
-
-
7
let!(:site1) { collection.sites.make properties:
-
{ select_one.es_code => "1", select_many.es_code => [1, 2], hierarchy.es_code => '100'} }
-
7
let!(:site2) { collection.sites.make properties:
-
{ select_many.es_code => [2]} }
-
7
let!(:site3) { collection.sites.make properties:
-
{ select_one.es_code => "1", hierarchy.es_code => '60'} }
-
-
1
it "filters select one field" do
-
1
search = collection.new_search
-
1
search.hierarchy(select_one.es_code, "1")
-
1
assert_results search, site1, site3
-
end
-
-
1
it "filter select many field" do
-
1
search = collection.new_search
-
1
search.hierarchy(select_many.es_code, "2")
-
1
assert_results search, site1, site2
-
end
-
-
1
it "filter select many field with no value" do
-
1
search = collection.new_search
-
1
search.hierarchy(select_many.es_code, nil)
-
1
assert_results search, site3
-
end
-
-
1
it "filter select one field with no value" do
-
1
search = collection.new_search
-
1
search.hierarchy(select_one.es_code, nil)
-
1
assert_results search, site2
-
end
-
-
1
it "filter hierarchy field" do
-
1
search = collection.new_search
-
1
search.hierarchy(hierarchy.es_code, "60")
-
1
assert_results search, site3
-
end
-
-
1
it "filter hierarchy field with no value" do
-
1
search = collection.new_search
-
1
search.hierarchy(hierarchy.es_code, nil)
-
1
assert_results search, site2
-
end
-
end
-
-
1
def assert_results(search, *sites)
-
104
expect(search.results.map{|r| r['_id'].to_i}).to match_array(sites.map(&:id))
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Site::CleanupConcern do
-
6
let!(:user) { User.make }
-
6
let!(:collection) { user.create_collection Collection.make_unsaved }
-
6
let!(:layer) { collection.layers.make user: user }
-
6
let!(:beds) { layer.numeric_fields.make :code => 'beds' }
-
6
let!(:area) { layer.numeric_fields.make :code => 'area', config: { :allows_decimals => "true" } }
-
6
let!(:many) { layer.select_many_fields.make :code => 'many', :config => {'options' => [{'id' => 1, 'code' => 'foo', 'label' => 'A glass of water'}, {'id' => 2, 'code' => 'bar', 'label' => 'A bottle of wine'}]} }
-
6
let!(:one) { layer.select_one_fields.make :code => 'one', :config => {'options' => [{'id' => 1, 'code' => 'foo', 'label' => 'A glass of water'}, {'id' => 2, 'code' => 'bar', 'label' => 'A bottle of wine'}]} }
-
-
1
it "converts properties values to int if the field does not allow decimals" do
-
1
site = collection.sites.make properties: {beds.es_code => '123'}
-
1
expect(site.properties[beds.es_code]).to eq(123)
-
end
-
-
1
it "converts properties values to float if the field allows decimals" do
-
1
site = collection.sites.make properties: {area.es_code => '123.4'}
-
1
expect(site.properties[area.es_code]).to eq(123.4)
-
end
-
-
1
it "convert select_many to ints" do
-
1
site = collection.sites.make properties: {many.es_code => ['1', '2']}
-
1
expect(site.properties[many.es_code]).to eq([1, 2])
-
end
-
-
1
it "convert select_one to ints" do
-
1
site = collection.sites.make properties: {one.es_code => '1'}
-
1
expect(site.properties[one.es_code]).to eq(1)
-
end
-
-
1
it "removes empty properties after save" do
-
1
site = collection.sites.make properties: { beds.es_code => nil}
-
1
expect(site.properties).not_to have_key(beds.es_code)
-
end
-
end
-
-
1
require 'spec_helper'
-
-
1
describe SiteHistory, :type => :model do
-
2
it { is_expected.to belong_to :site }
-
-
1
it "should create ES index" do
-
1
index_name = Collection.index_name 32, snapshot: "last_year"
-
-
1
client = Elasticsearch::Client.new
-
1
client.indices.create index: index_name
-
-
1
begin
-
1
site_history = SiteHistory.make
-
-
1
site_history.store_in index_name
-
-
1
expect(client.indices.exists(index: index_name)).to be_truthy
-
-
1
results = client.search index: index_name
-
1
results = results["hits"]["hits"]
-
-
1
expect(results.length).to eq(1)
-
1
expect(results.first["_source"]["name"]).to eq(site_history.name)
-
1
expect(results.first["_source"]["id"]).to eq(site_history.site_id)
-
1
expect(results.first["_source"]["properties"]).to eq(site_history.properties)
-
1
expect(results.first["_source"]["location"]["lat"]).to eq(site_history.lat)
-
1
expect(results.first["_source"]["location"]["lon"]).to eq(site_history.lng)
-
ensure
-
1
client.indices.delete index: index_name
-
end
-
end
-
-
end
-
-
1
require 'spec_helper'
-
-
1
describe Site::PrefixConcern do
-
1
it "should get first id_with_prefix" do
-
1
site = Site.make_unsaved
-
1
expect(site.generate_id_with_prefix).to eq('AA1')
-
end
-
-
1
it "should get id_with_prefix" do
-
1
site = Site.make
-
1
site.id_with_prefix = "AW22" and site.save
-
1
expect(site.generate_id_with_prefix).to eq('AW23')
-
end
-
-
1
it "should get id with two prefixex" do
-
1
site = Site.make(:id_with_prefix => 'AD999')
-
1
prefix_and_id = site.get_id_with_prefix
-
1
expect(prefix_and_id.size).to eq(2)
-
1
expect(prefix_and_id[0]).to eq('AD')
-
1
expect(prefix_and_id[1]).to eq('999')
-
end
-
end
-
-
1
require 'spec_helper'
-
-
1
describe SiteReminder, :type => :model do
-
1
describe 'telemetry' do
-
4
let!(:collection) { Collection.make }
-
4
let!(:site) { Site.make collection: collection }
-
-
1
it 'should touch collection lifespan on create' do
-
1
site_reminder = SiteReminder.make_unsaved site: site
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
site_reminder.save
-
end
-
-
1
it 'should touch collection lifespan on update' do
-
1
site_reminder = SiteReminder.make site: site
-
1
site_reminder.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
site_reminder.save
-
end
-
-
1
it 'should touch collection lifespan on destroy' do
-
1
site_reminder = SiteReminder.make site: site
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
site_reminder.destroy
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Site do
-
3
let(:user) { User.make }
-
2
it { is_expected.to belong_to :collection }
-
-
1
def history_concern_class
-
12
described_class
-
end
-
-
1
def history_concern_foreign_key
-
2
described_class.name.foreign_key
-
end
-
-
1
def history_concern_histories
-
1
"#{described_class}_histories"
-
end
-
-
1
it_behaves_like "it includes History::Concern"
-
-
11
let(:collection) { Collection.make }
-
11
let(:layer) { collection.layers.make }
-
11
let(:room) { layer.numeric_fields.make name: 'room' }
-
11
let(:desk) { layer.text_fields.make name: 'desk' }
-
10
let(:creation) { layer.date_fields.make name: 'creation'}
-
-
10
let(:site) { collection.sites.make properties: { room.id.to_s => '50', desk.id.to_s => 'bla bla', creation.id.to_s => '2012-09-22T00:00:00Z' } }
-
-
1
it "return as a hash of field_name and its value" do
-
1
expect(site.human_properties).to eq({'room' => 50, 'desk' => 'bla bla', 'creation' => '09/22/2012' })
-
end
-
-
1
it "should save yes_no property with value 'false' " do
-
1
yes_no_field = layer.yes_no_fields.make :code => 'X Ray machine'
-
1
site.properties[yes_no_field.es_code] = false
-
1
site.save!
-
1
site.reload
-
1
expect(site.properties[yes_no_field.es_code]).to eq(false)
-
end
-
-
1
describe "create or update from hash" do
-
1
before(:each) do
-
2
@hash = { "collection_id" => layer.collection.id,
-
"name" => "site1", "lat" => "11.1", "lng" => "12.1",
-
"existing_fields" => {"field_#{room.id}" => {"field_id" => room.id, "value" => "10"},
-
"field_#{desk.id}" => {"field_id" => desk.id, "value" => "test"}}}
-
2
@hash.merge!("current_user" => user)
-
2
@site_count = Site.count
-
end
-
-
1
it "should create a new site when site id is missing or nil" do
-
1
site1 = Site.create_or_update_from_hash!(@hash)
-
1
expect(site1).not_to be_nil
-
end
-
-
1
it "should update an existing site" do
-
1
@hash["site_id"] = site.id
-
1
site1 = Site.create_or_update_from_hash!(@hash)
-
1
expect(site1.name).to eq(@hash["name"])
-
end
-
end
-
-
1
it "should get id and name" do
-
1
expect(Site.get_id_and_name([site.id])).to eq([{'id' => site.id, 'name' => site.name}])
-
end
-
-
1
it "should save without problems after field is deleted" do
-
1
site # This line is needed because let(:site) is lazy
-
-
1
room.destroy
-
-
1
site.properties = site.properties
-
1
site.save!
-
end
-
-
1
describe '.valid_lat_lng' do
-
1
it "should return false when invalid lat" do
-
1
site.lat = 105.23
-
1
site.lng = 102.24
-
1
expect(site.send(:valid_lat_lng)).to eq(false)
-
end
-
-
1
it "should return false when invalid lng" do
-
1
site.lat = 95.23
-
1
site.lng = 190.24
-
1
expect(site.send(:valid_lat_lng)).to eq(false)
-
end
-
-
1
it "should return true when valid lat lng" do
-
1
site.lat = 88.23
-
1
site.lng = 120.24
-
1
expect(site.send(:valid_lat_lng)).to eq(true)
-
end
-
-
1
it "should return true when lat lng is nil" do
-
1
site.lat = nil
-
1
site.lng = nil
-
1
expect(site.send(:valid_lat_lng)).to eq(true)
-
end
-
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe SitesPermission, :type => :model do
-
2
it { is_expected.to belong_to :membership }
-
-
1
describe "convert to json" do
-
1
describe '#to_json' do
-
2
subject { super().to_json }
-
2
it { is_expected.not_to include "\"id\":" }
-
end
-
-
1
describe '#to_json' do
-
2
subject { super().to_json }
-
2
it { is_expected.not_to include "\"membership_id\":" }
-
end
-
-
1
describe '#to_json' do
-
2
subject { super().to_json }
-
2
it { is_expected.not_to include "\"created_at\":" }
-
end
-
-
1
describe '#to_json' do
-
2
subject { super().to_json }
-
2
it { is_expected.not_to include "\"updated_at\":" }
-
end
-
end
-
-
1
it "should have no_permission" do
-
1
expect(SitesPermission.no_permission).to eq({ read: nil, write: nil })
-
end
-
-
1
describe 'telemetry' do
-
7
let!(:user) { User.make }
-
7
let!(:collection) { Collection.make }
-
7
let!(:membership) { Membership.make collection: collection, user: user }
-
-
1
it 'should touch collection lifespan on create' do
-
1
sites_permission = SitesPermission.make_unsaved membership: membership
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
sites_permission.save
-
end
-
-
1
it 'should touch collection lifespan on update' do
-
1
sites_permission = SitesPermission.make membership: membership
-
1
sites_permission.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
sites_permission.save
-
end
-
-
1
it 'should touch collection lifespan on destroy' do
-
1
sites_permission = SitesPermission.make membership: membership
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
sites_permission.destroy
-
end
-
-
1
it 'should touch user lifespan on create' do
-
1
sites_permission = SitesPermission.make_unsaved membership: membership
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
sites_permission.save
-
end
-
-
1
it 'should touch user lifespan on update' do
-
1
sites_permission = SitesPermission.make membership: membership
-
1
sites_permission.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
sites_permission.save
-
end
-
-
1
it 'should touch user lifespan on destroy' do
-
1
sites_permission = SitesPermission.make membership: membership
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
sites_permission.destroy
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Snapshot, :type => :model do
-
1
describe "validations" do
-
2
let!(:snapshot) { Snapshot.make }
-
-
2
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:collection_id) }
-
end
-
-
10
let(:collection) { Collection.make }
-
-
1
before(:each) do
-
9
stub_time '2011-01-01 10:00:00 -0500'
-
-
9
layer = collection.layers.make
-
9
@field = layer.numeric_fields.make code: 'beds'
-
-
9
@site1 = collection.sites.make name: 'site1 last year'
-
9
@site2 = collection.sites.make name: 'site2 last year'
-
-
9
stub_time '2012-06-05 12:17:58 -0500'
-
9
@field2 = layer.numeric_fields.make code: 'beds2'
-
-
9
@site3 = collection.sites.make name: 'site3 today'
-
9
@site4 = collection.sites.make name: 'site4 today'
-
end
-
-
1
it "should create index with sites" do
-
1
date = '2011-01-01 10:00:00 -0500'.to_time
-
1
snapshot = collection.snapshots.create! date: date, name: 'last_year'
-
-
1
index_name = Collection.index_name collection.id, snapshot_id: snapshot.id
-
1
results = Elasticsearch::Client.new.search index: index_name
-
1
results = results["hits"]["hits"]
-
1
expect(results.map { |x| x['_source']['id'] }.sort).to eq([@site1.id, @site2.id])
-
-
# Also check mapping
-
mapping = Elasticsearch::Client.new.indices.get_mapping index: snapshot.index_name, type: 'site'
-
expect(mapping[snapshot.index_name]['mappings']['site']['properties']['properties']['properties']).to eq({@field.es_code => {'type' => 'double'}})
-
end
-
-
1
it "should destroy index on destroy" do
-
1
date = '2011-01-01 10:00:00 -0500'.to_time
-
-
1
snapshot = collection.snapshots.create! date: date, name: 'last_year'
-
1
snapshot.destroy
-
-
1
index_name = Collection.index_name collection.id, snapshot_id: snapshot.id
-
1
expect(Elasticsearch::Client.new.indices.exists(index: index_name)).to be_falsey
-
end
-
-
1
it "collection should have histories" do
-
1
date = Time.now
-
1
site_histories = collection.site_histories.at_date(date)
-
1
expect(site_histories.count).to eq(4)
-
-
1
layer_histories = collection.layer_histories.at_date(date)
-
1
expect(layer_histories.count).to eq(1)
-
-
1
field_histories = collection.field_histories.at_date(date)
-
1
expect(field_histories.count).to eq(2)
-
end
-
-
1
it "collection should have histories for a past time" do
-
1
date = Time.parse('2011-01-02 10:00:00 -0500')
-
-
1
site_histories = collection.site_histories.at_date(date)
-
1
expect(site_histories.count).to eq(2)
-
-
1
layer_histories = collection.layer_histories.at_date(date)
-
1
expect(layer_histories.count).to eq(1)
-
-
1
field_histories = collection.field_histories.at_date(date)
-
1
expect(field_histories.count).to eq(1)
-
end
-
-
1
it "should delete history when collection is destroyed" do
-
1
collection.destroy
-
-
1
expect(collection.site_histories.count).to eq(0)
-
1
expect(collection.layer_histories.count).to eq(0)
-
1
expect(collection.field_histories.count).to eq(0)
-
end
-
-
1
it "should delete snapshots when collection is destroyed" do
-
1
collection.snapshots.create! date: Time.now, name: 'last_year'
-
1
expect(collection.snapshots.count).to eq(1)
-
-
1
collection.destroy
-
-
1
expect(collection.snapshots.count).to eq(0)
-
end
-
-
1
it "should delete userSnapshot if collection is destroyed" do
-
1
snapshot = collection.snapshots.create! date: Time.now, name: 'last_year'
-
1
user = User.make
-
1
snapshot.user_snapshots.create! user: user
-
1
expect(snapshot.user_snapshots.count).to eq(1)
-
-
1
collection.destroy
-
-
1
expect(UserSnapshot.where(user_id: user.id, snapshot_id: snapshot.id).count).to eq(0)
-
end
-
-
1
describe "info_for_collections_ids_and_user" do
-
1
it "should return empty hash if collections_ids is empty" do
-
1
user = User.make
-
1
expect(Snapshot.info_for_collections_ids_and_user([], user, "field")).to eq({})
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::ActivitiesCollector do
-
-
1
it "counts activities grouped by collection" do
-
1
period = InsteddTelemetry::Period.current
-
-
1
c1 = Collection.make
-
11
10.times { Activity.make collection: c1, item_type: 'site' }
-
-
1
c2 = Collection.make
-
18
17.times { Activity.make collection: c2, item_type: 'site' }
-
-
1
expect(stats(period)).to eq({
-
"counters" => [
-
{
-
"metric" => "activities",
-
"key" => { "collection_id" => c1.id },
-
"value" => 10
-
},
-
{
-
"metric" => "activities",
-
"key" => { "collection_id" => c2.id },
-
"value" => 17
-
}
-
]
-
})
-
end
-
-
1
it "takes into account current period" do
-
1
Timecop.freeze(Time.now)
-
1
c = Collection.make
-
11
10.times { Activity.make collection: c, item_type: 'site' }
-
1
p0 = InsteddTelemetry::Period.current
-
-
1
Timecop.freeze(Time.now + InsteddTelemetry::Period.span)
-
3
2.times { Activity.make collection: c, item_type: 'site' }
-
1
p1 = InsteddTelemetry::Period.current
-
-
1
expect(stats(p0)).to eq({
-
"counters" => [
-
{
-
"metric" => "activities",
-
"key" => { "collection_id" => c.id },
-
"value" => 10
-
}
-
]
-
})
-
-
1
expect(stats(p1)).to eq({
-
"counters" => [
-
{
-
"metric" => "activities",
-
"key" => { "collection_id" => c.id },
-
"value" => 12
-
}
-
]
-
})
-
end
-
-
1
it 'counts collections with 0 activities' do
-
1
to = Time.now
-
1
from = to - 1.week
-
1
period = InsteddTelemetry::Period.new beginning: from, end: to
-
-
1
c1 = Collection.make created_at: to - 5.days
-
1
c2 = Collection.make created_at: to - 1.day
-
1
c3 = Collection.make created_at: to + 1.day
-
-
1
Activity.make collection: c2, item_type: 'site', created_at: to + 1.day
-
1
Activity.make collection: c3, item_type: 'site', created_at: to + 3.days
-
-
1
counters = stats(period)['counters']
-
-
1
expect(counters.size).to eq(2)
-
1
expect(counters).to include({
-
"metric" => "activities",
-
"key" => { "collection_id" => c1.id },
-
"value" => 0
-
})
-
1
expect(counters).to include({
-
"metric" => "activities",
-
"key" => { "collection_id" => c2.id },
-
"value" => 0
-
})
-
end
-
-
1
def stats(period)
-
4
Telemetry::ActivitiesCollector.collect_stats(period)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::AlertConditionsCollector do
-
-
1
it "counts alert conditions by collection" do
-
1
period = InsteddTelemetry::Period.current
-
-
1
c1 = Collection.make
-
1
create_fields(c1, 3)
-
1
create_threshold_with_conditions(c1, 3)
-
1
create_threshold_with_conditions(c1, 2)
-
-
1
c2 = Collection.make
-
1
create_fields(c2, 7)
-
1
create_threshold_with_conditions(c2, 7)
-
-
1
expect(stats(period)).to eq({
-
"counters" => [
-
{
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => c1.id },
-
"value" => 5
-
},
-
{
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => c2.id },
-
"value" => 7
-
}
-
]
-
})
-
end
-
-
1
it "doesn't count thresholds created after current period" do
-
1
Timecop.freeze(Time.now)
-
-
1
c1 = Collection.make
-
1
create_fields(c1, 3)
-
1
create_threshold_with_conditions(c1, 3)
-
1
p0 = InsteddTelemetry::Period.current
-
-
1
Timecop.freeze(Time.now + InsteddTelemetry::Period.span)
-
1
create_threshold_with_conditions(c1, 1)
-
1
p1 = InsteddTelemetry::Period.current
-
-
1
expect(stats(p0)).to eq({
-
"counters" => [
-
{
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => c1.id },
-
"value" => 3
-
}
-
]
-
})
-
-
1
expect(stats(p1)).to eq({
-
"counters" => [
-
{
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => c1.id },
-
"value" => 4
-
}
-
]
-
})
-
end
-
-
1
it 'counts collections without alert conditions' do
-
1
period = InsteddTelemetry::Period.current
-
-
1
c1 = Collection.make
-
1
c2 = Collection.make
-
1
c3 = Collection.make created_at: period.end + 1.day
-
-
1
Timecop.freeze(period.end + 1.day) do
-
1
create_fields(c2, 3)
-
1
create_threshold_with_conditions(c2, 3)
-
-
1
create_fields(c3, 3)
-
1
create_threshold_with_conditions(c3, 3)
-
end
-
-
1
counters = stats(period)['counters']
-
-
1
expect(counters.size).to eq(2)
-
-
1
expect(counters).to include({
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => c1.id },
-
"value" => 0
-
})
-
-
1
expect(counters).to include({
-
"metric" => "alert_conditions",
-
"key" => { "collection_id" => c2.id },
-
"value" => 0
-
})
-
end
-
-
1
def create_fields(collection, count)
-
5
layer = collection.layers.make
-
5
count.times do |i|
-
19
Field::TextField.create!({
-
name: "foo_#{i}",
-
code: "foo_#{i}",
-
ord: i,
-
collection: collection,
-
layer: layer
-
})
-
end
-
5
collection.reload
-
end
-
-
1
def create_threshold_with_conditions(collection, count)
-
7
fields = collection.fields.take(count)
-
-
7
conditions = fields.map do |f|
-
22
{ field: f, op: :eq, type: :value, value: "asd" }
-
end
-
-
7
collection.thresholds.make conditions: conditions.to_a
-
end
-
-
1
def stats(period)
-
4
Telemetry::AlertConditionsCollector.collect_stats(period)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::FieldsCollector do
-
-
3
let(:period) { InsteddTelemetry::Period.current }
-
-
1
it 'counts fields by collection' do
-
1
collection_1 = Collection.make created_at: period.end - 1.day
-
1
collection_2 = Collection.make created_at: period.end - 7.days
-
1
collection_3 = Collection.make created_at: period.end + 1.days
-
-
1
layer_1 = Layer.make collection: collection_1
-
1
layer_2 = Layer.make collection: collection_2
-
1
layer_3 = Layer.make collection: collection_3
-
-
1
Field::NumericField.make collection: collection_1, layer: layer_1, created_at: period.end - 1.day
-
1
Field::SelectManyField.make collection: collection_1, layer: layer_1, created_at: period.end - 7.days
-
1
Field::UserField.make collection: collection_1, layer: layer_1, created_at: period.end - 60.days
-
1
Field::YesNoField.make collection: collection_1, layer: layer_1, created_at: period.end + 1.day
-
-
1
Field::UserField.make collection: collection_2, layer: layer_2, created_at: period.end - 10.days
-
1
Field::NumericField.make collection: collection_2, layer: layer_2, created_at: period.end - 27.days
-
-
1
Field::SelectManyField.make collection: collection_3, layer: layer_3, created_at: period.end + 5.days
-
-
1
stats = Telemetry::FieldsCollector.collect_stats period
-
1
counters = stats[:counters]
-
-
1
expect(counters.size).to eq(2)
-
-
1
expect(counters).to include({
-
metric: 'fields_by_collection',
-
key: {collection_id: collection_1.id},
-
value: 3
-
})
-
-
1
expect(counters).to include({
-
metric: 'fields_by_collection',
-
key: {collection_id: collection_2.id},
-
value: 2
-
})
-
end
-
-
1
it 'counts collections with 0 fields' do
-
1
collection_1 = Collection.make created_at: period.end - 5.days
-
1
collection_2 = Collection.make created_at: period.end - 1.day
-
1
collection_3 = Collection.make created_at: period.end + 1.day
-
-
1
layer_2 = Layer.make collection: collection_2
-
1
layer_3 = Layer.make collection: collection_3
-
-
1
Field::NumericField.make collection: collection_2, layer: layer_2, created_at: period.end + 1.day
-
1
Field::NumericField.make collection: collection_3, layer: layer_3, created_at: period.end + 3.days
-
-
1
stats = Telemetry::FieldsCollector.collect_stats period
-
1
counters = stats[:counters]
-
-
1
expect(counters.size).to eq(2)
-
1
expect(counters).to include({
-
metric: 'fields_by_collection',
-
key: { collection_id: collection_1.id },
-
value: 0
-
})
-
1
expect(counters).to include({
-
metric: 'fields_by_collection',
-
key: { collection_id: collection_2.id },
-
value: 0
-
})
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::Lifespan do
-
-
1
before :each do
-
3
@now = Time.now
-
3
Timecop.freeze(@now)
-
end
-
-
1
after :each do
-
3
Timecop.return
-
end
-
-
1
it 'updates the collection lifespan' do
-
1
collection = Collection.make created_at: @now - 1.week
-
-
1
expect(InsteddTelemetry).to receive(:timespan_update).with('collection_lifespan', {collection_id: collection.id}, collection.created_at, @now)
-
-
1
Telemetry::Lifespan.touch_collection collection
-
end
-
-
1
it 'updates the collection users lifespan' do
-
1
user1 = User.make
-
1
user2 = User.make
-
1
collection = Collection.make
-
1
Membership.make user: user1, collection: collection
-
1
Membership.make user: user2, collection: collection
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user1).at_least(:once)
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user2).at_least(:once)
-
-
1
Telemetry::Lifespan.touch_collection collection.reload
-
end
-
-
1
it 'updates the account lifespan' do
-
1
user = User.make created_at: @now - 1.week
-
-
1
expect(InsteddTelemetry).to receive(:timespan_update).with('account_lifespan', {account_id: user.id}, user.created_at, @now)
-
-
1
Telemetry::Lifespan.touch_user user
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::MembershipsCollector do
-
-
1
it "counts memberships grouped by collection_id" do
-
1
u1 = User.make
-
1
u2 = User.make
-
-
1
c1 = Collection.make
-
1
c2 = Collection.make
-
-
1
period = InsteddTelemetry::Period.current
-
-
1
Membership.make user: u1, collection: c1
-
1
Membership.make user: u1, collection: c2
-
-
1
Membership.make user: u2, collection: c1
-
-
1
expect(stats(period)).to eq({
-
"counters" => [
-
{
-
"metric" => "memberships",
-
"key" => { "collection_id" => c1.id },
-
"value" => 2
-
},
-
{
-
"metric" => "memberships",
-
"key" => { "collection_id" => c2.id },
-
"value" => 1
-
}
-
]
-
})
-
end
-
-
1
it "takes into account current period" do
-
1
Timecop.freeze(Time.now)
-
1
c = Collection.make
-
4
3.times { Membership.make user: User.make, collection: c }
-
1
p0 = InsteddTelemetry::Period.current
-
-
1
Timecop.freeze(Time.now + InsteddTelemetry::Period.span)
-
11
10.times { Membership.make user: User.make, collection: c }
-
1
p1 = InsteddTelemetry::Period.current
-
-
1
expect(stats(p0)).to eq({
-
"counters" => [
-
{
-
"metric" => "memberships",
-
"key" => { "collection_id" => c.id },
-
"value" => 3
-
}
-
]
-
})
-
-
1
expect(stats(p1)).to eq({
-
"counters" => [
-
{
-
"metric" => "memberships",
-
"key" => { "collection_id" => c.id },
-
"value" => 13
-
}
-
]
-
})
-
end
-
-
1
it 'counts collections with 0 memberships' do
-
1
to = Time.now
-
1
from = to - 1.week
-
1
period = InsteddTelemetry::Period.new beginning: from, end: to
-
-
1
c1 = Collection.make created_at: to - 5.days
-
1
c2 = Collection.make created_at: to - 1.day
-
1
c3 = Collection.make created_at: to + 1.day
-
-
1
Membership.make collection: c2, created_at: to + 1.day
-
1
Membership.make collection: c3, created_at: to + 3.days
-
-
1
counters = stats(period)['counters']
-
-
1
expect(counters.size).to eq(2)
-
1
expect(counters).to include({
-
"metric" => "memberships",
-
"key" => { "collection_id" => c1.id },
-
"value" => 0
-
})
-
1
expect(counters).to include({
-
"metric" => "memberships",
-
"key" => { "collection_id" => c2.id },
-
"value" => 0
-
})
-
end
-
-
1
def stats(period)
-
4
Telemetry::MembershipsCollector.collect_stats(period)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::NewCollectionsCollector do
-
-
1
it "counts collections created in current period" do
-
1
Timecop.freeze(Time.now)
-
1
p0 = currente_period
-
-
4
3.times { Collection.make }
-
-
1
expect(stats(p0)).to eq({
-
"counters" => [
-
{ "metric" => "new_collections", "key" => {}, "value" => 3 }
-
]
-
})
-
-
1
advance_period
-
1
p1 = currente_period
-
-
8
7.times { Collection.make }
-
-
1
expect(stats(p1)).to eq({
-
"counters" => [
-
{ "metric" => "new_collections", "key" => {}, "value" => 7 }
-
]
-
})
-
-
1
advance_period
-
11
10.times { Collection.make }
-
-
# do not count collections created in later periods
-
1
expect(stats(p1)).to eq({
-
"counters" => [
-
{ "metric" => "new_collections", "key" => {}, "value" => 7 }
-
]
-
})
-
end
-
-
1
def stats(period)
-
3
Telemetry::NewCollectionsCollector.collect_stats(period)
-
end
-
-
1
def currente_period
-
2
InsteddTelemetry::Period.current
-
end
-
-
1
def current_period_stats
-
stats(currente_period)
-
end
-
-
1
def advance_period
-
2
Timecop.freeze(Time.now + InsteddTelemetry::Period.span)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe Telemetry::SitesCollector do
-
-
1
it "counts sites grouped by collection_id" do
-
1
c1 = Collection.make
-
4
3.times { c1.sites.make }
-
-
1
c2 = Collection.make
-
6
5.times { c2.sites.make }
-
-
1
period = InsteddTelemetry::Period.current
-
-
1
expect(stats(period)).to eq({
-
"counters" => [
-
{
-
"metric" => "sites",
-
"key" => { "collection_id" => c1.id },
-
"value" => 3
-
},
-
{
-
"metric" => "sites",
-
"key" => { "collection_id" => c2.id },
-
"value" => 5
-
}
-
]
-
})
-
end
-
-
1
it "takes into account current period" do
-
1
Timecop.freeze(Time.now)
-
1
c = Collection.make
-
4
3.times { c.sites.make }
-
1
p0 = InsteddTelemetry::Period.current
-
-
1
Timecop.freeze(Time.now + InsteddTelemetry::Period.span)
-
11
10.times {c.sites.make }
-
1
p1 = InsteddTelemetry::Period.current
-
-
1
expect(stats(p0)).to eq({
-
"counters" => [
-
{
-
"metric" => "sites",
-
"key" => { "collection_id" => c.id },
-
"value" => 3
-
}
-
]
-
})
-
-
1
expect(stats(p1)).to eq({
-
"counters" => [
-
{
-
"metric" => "sites",
-
"key" => { "collection_id" => c.id },
-
"value" => 13
-
}
-
]
-
})
-
-
end
-
-
1
it 'counts collections with 0 sites' do
-
1
to = Time.now
-
1
from = to - 1.week
-
1
period = InsteddTelemetry::Period.new beginning: from, end: to
-
-
1
c1 = Collection.make created_at: to - 5.days
-
1
c2 = Collection.make created_at: to - 1.day
-
1
c3 = Collection.make created_at: to + 1.day
-
-
1
Site.make collection: c2, created_at: to + 1.day
-
1
Site.make collection: c3, created_at: to + 3.days
-
-
1
counters = stats(period)['counters']
-
-
1
expect(counters.size).to eq(2)
-
1
expect(counters).to include({
-
"metric" => "sites",
-
"key" => { "collection_id" => c1.id },
-
"value" => 0
-
})
-
1
expect(counters).to include({
-
"metric" => "sites",
-
"key" => { "collection_id" => c2.id },
-
"value" => 0
-
})
-
end
-
-
1
def stats(period)
-
4
Telemetry::SitesCollector.collect_stats(period)
-
end
-
-
end
-
1
require 'spec_helper'
-
-
1
describe UserSnapshot do
-
12
let!(:collection) { Collection.make }
-
12
let!(:user) { User.make }
-
18
let!(:snapshot1) { collection.snapshots.create! date: Date.yesterday, name: 'snp1' }
-
18
let!(:user_snapshot) { snapshot1.user_snapshots.create! user: user, collection: collection }
-
-
1
it "should delete previous snapshot per user and collection when creating a new one" do
-
1
snapshot_for_user = UserSnapshot.where user_id: user.id, collection_id: collection.id
-
1
expect(snapshot_for_user.count).to eq(1)
-
1
expect(snapshot_for_user.first.snapshot.name).to eq("snp1")
-
-
1
snapshot2 = collection.snapshots.create! date: Time.now , name: 'snp2'
-
1
snapshot2.user_snapshots.create! user: user, collection: collection
-
1
snapshot_for_user_new = UserSnapshot.where user_id: user.id, collection_id: collection
-
1
expect(snapshot_for_user_new.count).to eq(1)
-
1
expect(snapshot_for_user_new.first.snapshot.name).to eq("snp2")
-
end
-
-
1
describe "for" do
-
1
it "returns the corresponding UserSnapshot" do
-
1
s = UserSnapshot.for user, collection
-
-
1
expect(s.snapshot.name).to eq('snp1')
-
end
-
-
1
it "returns a valid unsaved UserSnapshot instance when there is not a previously saved one" do
-
1
user2 = User.make
-
-
1
s = UserSnapshot.for user2, collection
-
-
1
expect(s).not_to eq(nil)
-
1
expect(s.new_record?).to eq(true)
-
1
expect(s.collection).to eq(collection)
-
1
expect(s.user).to eq(user2)
-
end
-
end
-
-
1
describe "at_present?" do
-
1
it "is false if there's a snapshot loaded" do
-
1
expect(user_snapshot.at_present?).to eq(false)
-
end
-
-
1
it "is true if there isn't any snapshot loaded" do
-
1
s = UserSnapshot.new user: User.make, collection: collection
-
1
expect(s.at_present?).to eq(true)
-
end
-
end
-
-
1
describe "go_back_to_present" do
-
1
it "does not persist the UserSnapshot if it wasn't persisted before" do
-
1
s = UserSnapshot.new user: User.make, collection: collection
-
1
s.go_back_to_present!
-
1
expect(s.new_record?).to eq(true)
-
end
-
-
1
it "persists changes immediately" do
-
1
user_snapshot.go_back_to_present!
-
1
user_snapshot.reload
-
1
expect(user_snapshot.at_present?).to eq(true)
-
end
-
-
1
it "goes back to present if a snapshot was loaded" do
-
1
user_snapshot.go_back_to_present!
-
1
expect(user_snapshot.at_present?).to eq(true)
-
end
-
-
1
it "stays at present if a snapshot wasn't loaded" do
-
1
s = UserSnapshot.new user: User.make, collection: collection
-
-
1
s.go_back_to_present!
-
-
1
expect(s.at_present?).to eq(true)
-
end
-
end
-
-
1
describe "go_to" do
-
1
it "returns false and does nothing if there is not any snapshot with the given name" do
-
1
snapshot_before = user_snapshot.snapshot
-
-
1
expect(user_snapshot.go_to!('a_snapshot_that_doesnt_exist')).to eq(false)
-
-
1
expect(user_snapshot.snapshot).to eq(snapshot_before)
-
end
-
-
1
it "loads a snapshot with the given name" do
-
1
my_snapshot = collection.snapshots.create! date: Time.now , name: 'my snapshot'
-
1
user_snapshot.go_to!('my snapshot')
-
1
expect(user_snapshot.go_to!('my snapshot')).to eq(true)
-
1
expect(user_snapshot.snapshot_id).to eq(my_snapshot.id)
-
1
new_snapshot = Snapshot.find user_snapshot.snapshot_id
-
1
expect(new_snapshot.name).to eq('my snapshot')
-
end
-
end
-
-
1
describe 'telemetry' do
-
7
let!(:collection) { Collection.make }
-
7
let!(:snapshot) { Snapshot.make collection: collection }
-
7
let!(:user) { User.make }
-
-
1
it 'should touch collection lifespan on create' do
-
1
user_snapshot = UserSnapshot.make_unsaved snapshot: snapshot, user: user, collection: collection
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection).at_least(:once)
-
-
1
user_snapshot.save
-
end
-
-
1
it 'should touch collection lifespan on update' do
-
1
user_snapshot = UserSnapshot.make snapshot: snapshot, user: user, collection: collection
-
1
user_snapshot.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
user_snapshot.save
-
end
-
-
1
it 'should touch collection lifespan on destroy' do
-
1
user_snapshot = UserSnapshot.make snapshot: snapshot, user: user, collection: collection
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_collection).with(collection)
-
-
1
user_snapshot.destroy
-
end
-
-
1
it 'should touch user lifespan on create' do
-
1
user_snapshot = UserSnapshot.make_unsaved snapshot: snapshot, user: user, collection: collection
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
1
user_snapshot.save
-
end
-
-
1
it 'should touch user lifespan on update' do
-
1
user_snapshot = UserSnapshot.make snapshot: snapshot, user: user, collection: collection
-
1
user_snapshot.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user)
-
-
1
user_snapshot.save
-
end
-
-
1
it 'should touch user lifespan on destroy' do
-
1
user_snapshot = UserSnapshot.make snapshot: snapshot, user: user, collection: collection
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user)
-
-
1
user_snapshot.destroy
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe User do
-
2
it { is_expected.to have_many :memberships }
-
2
it { is_expected.to have_many :collections }
-
-
1
it "should be confirmed" do
-
1
user = User.make confirmed_at: nil
-
1
expect(user.confirmed?).to be_falsey
-
1
user.confirm!
-
1
expect(user.confirmed?).to be_truthy
-
end
-
-
1
it "creates a collection" do
-
1
user = User.make
-
1
collection = Collection.make_unsaved
-
1
expect(user.create_collection(collection)).to eq(collection)
-
1
expect(user.collections).to eq([collection])
-
1
expect(user.memberships.first).to be_admin
-
end
-
-
1
it "creates a collection with owner true" do
-
1
user = User.make
-
1
collection = Collection.make_unsaved
-
1
expect(user.create_collection(collection)).to eq(collection)
-
1
expect(user.collections).to eq([collection])
-
1
expect(user.memberships.first).to be_admin
-
1
expect(user.memberships.first).to be_owner
-
end
-
-
1
it "fails to create a collection if invalid" do
-
1
user = User.make
-
1
collection = Collection.make_unsaved
-
1
collection.name = nil
-
1
expect(user.create_collection(collection)).to be_falsey
-
1
expect(user.collections).to be_empty
-
end
-
-
1
context "duplicate phone numbers" do
-
2
let!(:user) { User.make :phone_number => '85592811844' }
-
-
1
it "should not allow to add a new user with duplicate phone" do
-
1
user2 = User.make
-
1
expect(User.create(:email => 'test@instedd.org', :password => 'AbCd456', :phone_number => '85592811844')).not_to be_valid
-
end
-
-
end
-
-
1
context "admins?" do
-
4
let!(:user) { User.make }
-
4
let!(:collection) { user.create_collection Collection.make_unsaved }
-
-
1
it "admins a collection" do
-
1
expect(user.admins?(collection)).to be_truthy
-
end
-
-
1
it "doesn't admin a collection if belongs but not admin" do
-
1
user2 = User.make
-
1
user2.memberships.create! :collection_id => collection.id
-
1
expect(user2.admins?(collection)).to be_falsey
-
end
-
-
1
it "doesn't admin a collection if doesn't belong" do
-
1
expect(User.make.admins?(collection)).to be_falsey
-
end
-
end
-
-
1
context "activities" do
-
3
let!(:user) { User.make }
-
3
let!(:collection) { user.create_collection Collection.make_unsaved }
-
-
1
before(:each) do
-
2
Activity.delete_all
-
end
-
-
1
it "returns activities for user membership" do
-
1
Activity.make collection_id: collection.id, user_id: user.id, item_type: 'collection', action: 'created', data: {:name => collection.name}, collection_name: collection.name
-
1
expect(user.activities.length).to eq(1)
-
end
-
-
1
it "doesn't return activities for user membership" do
-
1
user2 = User.make
-
1
Activity.make collection_id: collection.id, user_id: user.id, item_type: 'collection', action: 'created', data: {:name => collection.name}, collection_name: collection.name
-
1
expect(user2.activities.length).to eq(0)
-
end
-
end
-
-
1
describe "Permission" do
-
1
before(:each) do
-
6
@user1 = User.make
-
6
@user = User.create(:email => "demo@instedd.org", :password => "AbCd456", :phone_number => "855123456789")
-
6
@collection = Collection.make
-
6
@site = @collection.sites.make
-
6
@layer = @collection.layers.create(:name => "health center")
-
6
@properties =[{:code=>"AB", :value=>"26"}]
-
6
@field = Field.create(:collection_id => @collection.id, :layer_id => @layer.id, :code => "AB", :ord => 1, :kind => "numeric")
-
end
-
-
1
it "should be able to view and update layer" do
-
1
@collection.memberships.create(:user => @user, :admin => false)
-
1
@collection.layer_memberships.create( :layer_id => @layer.id, :read => true, :user_id => @user.id, :write => true)
-
1
Field::NumericField.create :collection_id => @collection.id, :layer_id => @layer.id, :code => "AB", :ord => 1
-
1
expect(@user.can_view?(@collection, @properties[0][:code])).to be_truthy
-
1
expect(@user.can_update?(@site, @properties)).to be_truthy
-
end
-
-
1
context "can update" do
-
1
it "should return true when user have write permission on layer" do
-
1
@collection.layer_memberships.create( :layer_id => @layer.id, :read => true, :user_id => @user.id, :write => true)
-
1
expect(@user.validate_layer_write_permission(@site, @properties)).to be_truthy
-
end
-
-
1
it "should return false when user don't have write permission on layer" do
-
1
expect(@user.validate_layer_write_permission(@site, @properties)).to be_falsey
-
end
-
-
1
it "should return true when two field have the same code 'AB' but difference collection_id" do
-
1
@collection1 = Collection.make
-
1
@layer1 = @collection1.layers.create(:name => "school")
-
1
@field1 = Field.create(:collection_id => @collection1.id, :layer_id => @layer1.id, :code => "AB", :ord => 1, :kind => "numeric")
-
1
@site1 = @collection1.sites.make
-
1
@collection1.layer_memberships.create( :layer_id => @layer1.id, :read => true, :user_id => @user.id, :write => true)
-
1
expect(@user.validate_layer_write_permission(@site1, @properties)).to be_truthy
-
end
-
end
-
-
1
context "can view" do
-
1
it "should return true when user have read permission on layer" do
-
1
@collection.layer_memberships.create( :layer_id => @layer.id, :read => true, :user_id => @user.id, :write => true)
-
1
expect(@user.validate_layer_read_permission(@collection, @properties[0][:code])).to be_truthy
-
end
-
-
1
it "should return false when user don't have write permission on layer" do
-
1
expect(@user.validate_layer_read_permission(@site, @properties[0][:code])).to be_falsey
-
end
-
end
-
end
-
-
1
it "should encrypt all users password" do
-
1
User.connection.execute "INSERT INTO `users` (`id`, `email`, `encrypted_password`, `created_at`, `updated_at`) VALUES (22, 'foo@example.com', 'BAr12345', CURDATE(), CURDATE())"
-
1
User.encrypt_users_password
-
1
expect(User.first.encrypted_password).not_to eq('BAr12345')
-
end
-
-
1
describe 'gateway' do
-
2
let(:user_1){ User.make }
-
2
let!(:gateway) { user_1.channels.make name: 'default', ticket_code: '1234', basic_setup: true}
-
-
1
it 'should return gateway under user' do
-
1
expect(user_1.get_gateway).to eq gateway
-
end
-
end
-
-
1
it "should change datetime based on user timezone" do
-
1
User.connection.execute "INSERT INTO `users` (`id`, `email`, `encrypted_password`, `time_zone`, `created_at`, `updated_at`) VALUES (22, 'foo@example.com', 'BAr12345', 'Bangkok', CURDATE(), CURDATE())"
-
1
Time.zone = User.first.time_zone
-
1
expect(User.first.created_at.in_time_zone(User.first.time_zone).to_s).to eq User.first.created_at.to_s
-
end
-
-
1
describe 'telemetry' do
-
1
it 'should touch lifespan on create' do
-
1
user = User.make_unsaved
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user)
-
-
1
user.save
-
end
-
-
1
it 'should touch lifespan on update' do
-
1
user = User.make
-
1
user.touch
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user)
-
-
1
user.save
-
end
-
-
1
it 'should touch lifespan on destroy' do
-
1
user = User.make
-
-
1
expect(Telemetry::Lifespan).to receive(:touch_user).with(user)
-
-
1
user.destroy
-
end
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe Xform do
-
-
1
let!(:template) { }
-
end
-
1
require 'spec_helper'
-
1
describe SmsNuntium do
-
2
let!(:users){User.create(:email => 'user2@instedd.org', :password => 'ABcd12345', :phone_number => '855123456789')}
-
2
let(:collection) { Collection.make }
-
1
it 'should send sms to correct user' do
-
1
nuntium = double("Nuntium")
-
1
expect(Nuntium).to receive(:new_from_config).and_return(nuntium)
-
1
expect(nuntium).to receive(:send_ao).with([{:from =>"resourcemap", :to => "sms://855123456789", :body => "alert", :suggested_channel => "testing" }])
-
1
SmsNuntium.notify_sms [users.phone_number], "alert", "testing", collection.id
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "routes for Api Collections" do
-
1
it "should route to show collection" do
-
1
expect(get("/api/collections/1.rss")).
-
to route_to(
-
controller: 'api/collections',
-
action: 'show',
-
id: '1',
-
format: 'rss'
-
)
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "routes for Sites Api" do
-
1
it "should route to show site" do
-
1
expect(get("/api/sites/1.rss")).
-
to route_to(
-
controller: 'api/sites',
-
action: 'show',
-
id: '1',
-
format: 'rss'
-
)
-
end
-
end
-
1
require 'spec_helper'
-
-
1
describe "routes for Memberships" do
-
1
it "should route to search" do
-
1
expect(get("/collections/1/memberships/search")).
-
to route_to(
-
controller: 'memberships',
-
action: 'search',
-
collection_id: '1'
-
)
-
end
-
end
-
1
module Capybara::AccountHelper
-
-
-
end
-
1
module Capybara::CollectionHelper
-
-
1
def create_collection_for (user)
-
collection = user.collections.make name: 'Central Hospital'
-
user.memberships.make collection: collection, admin: true
-
collection
-
end
-
-
1
def create_site_for(collection)
-
collection.sites.make(:name => 'Health Center', :lng => 14.3574, :lat => 26.7574)
-
end
-
-
1
def create_layer_for(collection)
-
collection.layers.make(:name => 'Central Hospital Layer 1')
-
end
-
-
1
def create_field_for (layer)
-
layer.text_fields.make(:name => 'Central Hospital Layer 1 Field', :code => 'CHL1F')
-
end
-
-
end
-
1
module Capybara::CustomFinders
-
-
1
def filter(name)
-
"div[data-filter-type=\"#{name.camelcase}\"]"
-
end
-
-
1
def confirm_popup
-
page.driver.browser.switch_to.alert.accept
-
end
-
-
1
def dismiss_popup
-
page.driver.browser.switch_to.alert.dismiss
-
end
-
end
-
1
module Capybara::MailHelper
-
-
-
end
-
1
class Capybara::Session
-
-
1
def save_screenshot_with_path(path)
-
save_screenshot_without_path(File.join(Rails.root, "spec/integration/screenshots/", path))
-
end
-
1
alias_method_chain :save_screenshot, :path
-
-
1
def attach_file_with_path(locator, path)
-
attach_file_without_path(locator, File.join(Rails.root, "spec/integration/uploads/", path))
-
end
-
1
alias_method_chain :attach_file, :path
-
-
1
def send_key(jquery_selector, key)
-
script = "var e = $.Event('keydown', { keyCode: #{key} }); $('#{jquery_selector}').trigger(e); "
-
execute_script script
-
end
-
-
end
-
1
module Capybara::SettingsHelper
-
-
-
end
-
1
shared_examples "it includes History::Concern" do
-
-
2
it "should store history on creation" do
-
2
model = history_concern_class.make_unsaved
-
2
expect(model.histories.count).to eq(0)
-
2
model.save!
-
2
expect(model.histories.count).to eq(1)
-
end
-
-
2
it "should store history on update" do
-
2
model = history_concern_class.make
-
2
expect(model.histories.count).to eq(1)
-
2
model.name = "New name"
-
2
model.save!
-
2
expect(model.name).to eq("New name")
-
2
expect(model.histories.count).to eq(2)
-
2
expect(model.histories.last.name).to eq("New name")
-
end
-
-
2
it "should set valid_to in history on update" do
-
2
model = history_concern_class.make
-
2
model.name = "New name"
-
2
model.save!
-
2
expect(model.histories.count).to eq(2)
-
2
expect(model.histories.first.valid_to.to_i).to eq(model.updated_at.to_i)
-
2
expect(model.histories.last.valid_to).to be_nil
-
end
-
-
2
it "should set valid_to in history before delete" do
-
2
model = history_concern_class.make
-
2
expect(model.histories.count).to eq(1)
-
2
expect(model.histories.last.valid_to).to be_nil
-
-
2
stub_time '2020-01-01 10:00:00 -0500'
-
-
2
model.destroy
-
2
histories = model.histories
-
2
expect(history_concern_class.where(id: model.id).count).to eq(0)
-
2
expect(histories.count).to eq(1)
-
2
expect(histories.last.valid_to).to eq(Time.now)
-
end
-
-
2
it "shouldn't get current history when destroyed" do
-
2
model = history_concern_class.make
-
2
model.destroy
-
2
model_history = model.current_history
-
2
expect(model_history).to be_nil
-
end
-
-
2
it "should get current history for new model" do
-
2
model = history_concern_class.make
-
2
model_history = model.current_history
-
2
expect(model_history).to be
-
2
assert_model_equals_history model, model_history
-
2
expect(model_history.valid_to).to be_nil
-
2
expect(model_history.valid_since.to_i).to eq(model.created_at.to_i)
-
end
-
-
2
it "should get current history for updated model" do
-
2
stub_time '2010-01-01 09:00:00 -0500'
-
2
model = history_concern_class.make
-
-
2
stub_time '2010-02-02 09:00:00 -0500'
-
2
model.name = "new name"
-
2
model.save!
-
-
2
model_history = model.current_history
-
2
expect(model_history).to be
-
2
expect(model_history.valid_to).to be_nil
-
2
assert_model_equals_history model, model_history
-
2
expect(model_history.valid_since.to_i).to eq(model.updated_at.to_i)
-
end
-
-
2
it "should not get new elements in history for date" do
-
2
collection = Collection.make
-
-
2
stub_time '2011-01-01 10:00:00 -0500'
-
-
2
history_concern_class.make name: '1 last year', collection_id: collection.id
-
2
history_concern_class.make name: '2 last year', collection_id: collection.id
-
-
2
stub_time '2012-06-05 12:17:58 -0500'
-
-
2
history_concern_class.make name: '3 today', collection_id: collection.id
-
2
history_concern_class.make name: '4 today', collection_id: collection.id
-
-
2
date = '2011-01-01 10:00:00 -0500'.to_time
-
-
2
histories = collection.send(history_concern_histories.downcase).at_date(date)
-
2
expect(histories.count).to eq(2)
-
end
-
-
2
def assert_model_equals_history(model, history)
-
4
model.attributes.keys.each do |key|
-
44
expect(model[key]).to eq(history[key]) unless ['id', 'created_at', 'updated_at'].include? key
-
end
-
4
expect(history[history_concern_foreign_key]).to eq(model.id)
-
end
-
end
-
1
RSpec.shared_examples 'user lifespan' do |klass, params|
-
let!(:user) { User.make }
-
-
it 'should touch user lifespan on create' do
-
record = klass.make_unsaved user_lifespan_params(params)
-
-
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
record.save
-
end
-
-
it 'should touch user lifespan on update' do
-
record = klass.make user_lifespan_params(params)
-
record.touch
-
-
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
record.save
-
end
-
-
it 'should touch user lifespan on destroy' do
-
record = klass.make user_lifespan_params(params)
-
-
expect(Telemetry::Lifespan).to receive(:touch_user).with(user).at_least(:once)
-
-
record.destroy
-
end
-
-
def user_lifespan_params(params)
-
{user: user}.merge(params || {})
-
end
-
end